Sample docs and Postman Collection for using Okta's Authentication API and Factors API.
This document illustrates the basic API calls needed to register a user, enroll them in MFA factors, challenge the user for an MFA factor, and check for an active Okta session. The API calls and attached Postman Collection are mapped to Okta's Transaction State model to help better understand the various states of a user account in Okta, and how MFA policies are used to determine when a user must enroll in a factor.
The documentation below and the included Postman collection invoke Okta's REST APIs directly. Okta also provides a JavaScript library that wraps some of these calls to make deploying a custom sign-in page even easier. Okta's Auth JavaScript SDK can be found on Github: okta-auth-js.
https://developer.okta.com/docs/api/resources/authn#primary-authentication Postman Request: Primary Authentication
curl -X POST \
https://oktalane.okta.com/api/v1/authn \
-H 'Accept: application/json' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: b9e5e0cd-a8e1-44c2-9cdf-25f0b5f5daf2' \
-d '{
"username": "jeff.beck",
"password": "xaxaxaxaxa",
"options": {
"multiOptionalFactorEnroll": true,
"warnBeforePasswordExpired": false
}
}'
If no policy rule requires MFA, the response status will be SUCCESS and include a sessionToken that can be exchanged for a sessionCookie (see below).
{
"expiresAt": "2018-10-03T18:32:22.000Z",
"status": "SUCCESS",
"sessionToken": "20111BRxe-iyWLZ0TnEN7zwaNTZ9LaY4tf3MwSYKju8kZMx-f-TTC-d",
"_embedded": {
"user": {
"id": "00u2e9pzr0aCdtXuI1t3",
"passwordChanged": "2017-05-24T19:52:29.000Z",
"profile": {
"login": "jeff.beck@acme.com",
"firstName": "Jeff",
"lastName": "Beck",
"locale": "en",
"timeZone": "America/Los_Angeles"
}
}
}
}
To exhange the sessionToken for a Okta Session. Okta will drop a session cookie called sid in the domain of your Okta org: Postman Request: sessionCookieRedirect
{{url}}/login/sessionCookieRedirect?token={{sessionToken}}&redirectUrl={{redirectUrl}}
Where sessionToken is the sessionToken value received in the response to Primary Authentication /authn, and redirectUrl is where Okta should redirect the user after establishing a session. Typically, this is a landing page or back to your custom sign-in page. Note the requirements listed here: https://developer.okta.com/use_cases/authentication/session_cookie#retrieving-a-session-cookie-by-visiting-a-session-redirect-link.
Note: In order to check for an active session, you can call the /api/v1/sessions/me endpoint (see Get Current Session below).
If a policy rule requires MFA, the response from Primary Authentication will indicate status of MFA_REQUIRED, and will include a list of any MFA factors that the user has already enrolled.
{
"stateToken": "00zvsJ80BHTgWYo8iVtRdfEUNrqpZsSx4w-DLebNf3",
"expiresAt": "2018-10-03T20:30:06.000Z",
"status": "MFA_REQUIRED",
"_embedded": {
"user": {
"id": "00u2e9pzr0aCdtXuI1t3",
"passwordChanged": "2017-05-24T19:52:29.000Z",
"profile": {
"login": "jeff.beck@acme.com",
"firstName": "Jeff",
"lastName": "Beck",
"locale": "en",
"timeZone": "America/Los_Angeles"
}
},
"factors": [
{
"id": "sms2s9jimvGguB7zY1t7",
"factorType": "sms",
"provider": "OKTA",
"vendorName": "OKTA",
"profile": {
"phoneNumber": "+1 XXX-XXX-4259"
},
"_links": {
"verify": {
"href": "https://oktalane.okta.com/api/v1/authn/factors/sms2e9jimvGguxaxat7/verify",
"hints": {
"allow": [
"POST"
]
}
}
}
},
{
"id": "ufs2e9klmhQWN7jX51t7",
"factorType": "question",
"provider": "OKTA",
"vendorName": "OKTA",
"profile": {
"question": "name_of_first_plush_toy",
"questionText": "What is the name of your first stuffed animal?"
},
"_links": {
"verify": {
"href": "https://oktalane.okta.com/api/v1/authn/factors/ufs2e9klmhQWN7xaxaxa7/verify",
"hints": {
"allow": [
"POST"
]
}
}
}
},
{
"id": "uft4ox35mszVJHRg21t7",
"factorType": "token:software:totp",
"provider": "GOOGLE",
"vendorName": "GOOGLE",
"profile": {
"credentialId": "jeff.beck@acme.com"
},
"_links": {
"verify": {
"href": "https://oktalane.okta.com/api/v1/authn/factors/uft4ox35msxaxaxat7/verify",
"hints": {
"allow": [
"POST"
]
}
}
}
}
],
"policy": {
"allowRememberDevice": false,
"rememberDeviceLifetimeInMinutes": 0,
"rememberDeviceByDefault": false,
"factorsPolicyInfo": {}
}
},
"_links": {
"cancel": {
"href": "https://oktalane.okta.com/api/v1/authn/cancel",
"hints": {
"allow": [
"POST"
]
}
}
}
}
For this example, we will challenge our user to verify an SMS challenge.
Postman Request: Verify SMS Factor (new OTP challenge)
curl -X POST \
https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/sms2e9jimvGguxaxat7/verify \
-H 'Accept: application/json' \
-H 'Authorization: SSWS 009i9BR9qxaxaxaxaxaxasrHeTrHGef-l3UvGxaxarHGef' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: 00168423-58b0-4e03-aeb2-826857303fab' \
-d '{
} '
Where factorId is the ID of the SMS factor from the /authn response above. We will receive a response similar to below, and the user will receive an SMS message with a verification code at the phone number they registered when enrolling the SMS factor.
{
"factorResult": "CHALLENGE",
"profile": {
"phoneNumber": "+15052694259"
},
"_links": {
"verify": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/sms2e9jimvGguxaxat7/verify",
"hints": {
"allow": [
"POST"
]
}
},
"factor": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/sms2e9jimvGguxaxat7",
"hints": {
"allow": [
"GET",
"DELETE"
]
}
}
}
}
To verify the SMS challenge, call the same API but include the verification code provided by the user: Postman Request: Verify SMS Factor (verify token)
curl -X POST \
https://oktalane.okta.com/api/v1/authn/factors/sms2e9jimvGguxaxat7/verify \
-H 'Accept: application/json' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: 194e7126-fe0b-4c36-a114-e2129c538f70' \
-d '{
"stateToken": "00zvsJ80BHTgWYo8iVtRdfEUNrqpZsSx4w-DLebNf3",
"passCode": "431261"
}'
If the verification succeeds, our response will include a sessionToken that can be exchanged for an Okta session as described above in the Primary Authentication section.
{
"expiresAt": "2018-10-03T20:52:59.000Z",
"status": "SUCCESS",
"sessionToken": "20111cnsvjlsAvS1drP_rV3pHFkVD2AfEupFMVvMf62B2wPQdvRo5Fx",
"_embedded": {
"user": {
"id": "00u2e9hju0dCitSuI1t7",
"passwordChanged": "2017-05-24T19:52:29.000Z",
"profile": {
"login": "jeff.beck@acme.com",
"firstName": "Jeff",
"lastName": "Beck",
"locale": "en",
"timeZone": "America/Los_Angeles"
}
}
}
}
This example shows how to enroll Google Authenticator as an MFA factor. Postman Request: Enroll Google Authenticator Factor
curl -X POST \
https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors \
-H 'Accept: application/json' \
-H 'Authorization: SSWS 009i9BR9qxaxaxaxaxaxasrHeTrHGef-l3UvGxaxarHGef' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: fd9598e7-6022-4b23-a923-efcb694b836e' \
-d '{
"factorType": "token:software:totp",
"provider": "GOOGLE"
}'
The response will include a link to the QR code to display to the user:
{
"id": "uft8gh35mszUCXKg21t7",
"factorType": "token:software:totp",
"provider": "GOOGLE",
"vendorName": "GOOGLE",
"status": "PENDING_ACTIVATION",
"created": "2018-10-02T21:28:08.000Z",
"lastUpdated": "2018-10-02T21:28:08.000Z",
"profile": {
"credentialId": "jeff.beck@acme.com"
},
"_links": {
"activate": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/uft8gh35msxaxaxa21t7/lifecycle/activate",
"hints": {
"allow": [
"POST"
]
}
},
"self": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/uft8gh35msxaxaxa21t7",
"hints": {
"allow": [
"GET"
]
}
},
"user": {
"href": "https://oktalane.okta.com/api/v1/users/uft8gh35msxaxaxa21t7",
"hints": {
"allow": [
"GET"
]
}
}
},
"_embedded": {
"activation": {
"timeStep": 30,
"sharedSecret": "UNEAPF65QJPOTJ2P",
"encoding": "base32",
"keyLength": 6,
"factorResult": "WAITING",
"_links": {
"qrcode": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/uft8gh35msxaxaxa21t7/qr/201114UIGNtbL-hUn4wVUJsESe1QBrLgKC7QlRVv_axN-xaxaxaxaxaxa",
"type": "image/png"
}
}
}
}
}
The user will scan the QR code with the Google Authenticator app, after which they can provide the OTP code to Okta to activate the factor. Postman Request: Activate TOTP Factor
curl -X POST \
https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/sms2e9jimvGxaxaY1t7/lifecycle/activate \
-H 'Accept: application/json' \
-H 'Authorization: SSWS 009i9BR9qxaxaxaxaxaxasrHeTrHGef-l3UvGxaxarHGef' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: e2cf3e17-efa7-46cb-8295-0735ac0f9018' \
-d '{
"passCode": "739841"
} '
Response:
{
"id": "uft8he99pkllUCXKg21t7",
"factorType": "token:software:totp",
"provider": "GOOGLE",
"vendorName": "GOOGLE",
"status": "ACTIVE",
"created": "2018-10-02T21:28:08.000Z",
"lastUpdated": "2018-10-02T21:29:58.000Z",
"profile": {
"credentialId": "jeff.beck@acme.com"
},
"_links": {
"self": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/uft8he99pkllUCXKg21t7",
"hints": {
"allow": [
"GET",
"DELETE"
]
}
},
"verify": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/uft8he99pkllUCXKg21t7/verify",
"hints": {
"allow": [
"POST"
]
}
},
"user": {
"href": "https://oktalane.okta.com/api/v1/users/uft8he99pkllUCXKg21t7",
"hints": {
"allow": [
"GET"
]
}
}
}
}
Postman Request: Get Current Session
curl -X GET \
https://oktalane.okta.com/api/v1/sessions/me \
-H 'Cache-Control: no-cache' \
-H 'Postman-Token: cefc7d11-8033-4f43-b4f7-25ddba8a3373'
If there is a current session, you will receive a response like:
{
"id": "102zYtGFjiaSHCussAtVkSkeg",
"userId": "00u2e9hju0dCitSuI1t7",
"login": "jeff.beck@acme.com",
"createdAt": "2018-10-03T20:54:16.000Z",
"expiresAt": "2018-10-03T22:59:14.000Z",
"status": "ACTIVE",
"lastPasswordVerification": "2018-10-03T20:54:16.000Z",
"lastFactorVerification": "2018-10-03T20:53:03.000Z",
"amr": [
"pwd"
],
"idp": {
"id": "00o2bioj34AlsZYJf1t7",
"type": "OKTA"
},
"mfaActive": true,
"_links": {
"self": {
"href": "https://oktalane.okta.com/api/v1/sessions/me",
"hints": {
"allow": [
"GET",
"DELETE"
]
}
},
"refresh": {
"href": "https://oktalane.okta.com/api/v1/sessions/me/lifecycle/refresh",
"hints": {
"allow": [
"POST"
]
}
},
"user": {
"name": "Jeff Beck",
"href": "https://oktalane.okta.com/api/v1/users/me",
"hints": {
"allow": [
"GET"
]
}
}
}
}
You should now see GOOGLE listed as an enrolled factor if you call the /factors endpoint:
curl -X GET \
https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors \
-H 'Accept: application/json' \
-H 'Authorization: SSWS 009i9BR9qxaxaxaxaxaxasrHeTrHGef-l3UvGxaxarHGef' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: 570602cf-9167-4b79-9e93-cbc0d8d03345'
[
{
"id": "ufs2e9klmhQWN7jX51t7",
"factorType": "question",
"provider": "OKTA",
"vendorName": "OKTA",
"status": "ACTIVE",
"created": "2017-05-24T19:52:42.000Z",
"lastUpdated": "2017-05-24T19:52:42.000Z",
"profile": {
"question": "name_of_first_plush_toy",
"questionText": "What is the name of your first stuffed animal?"
},
"_links": {
"questions": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/questions",
"hints": {
"allow": [
"GET"
]
}
},
"self": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/ufs2e9klmhQWN7jX51t7",
"hints": {
"allow": [
"GET",
"DELETE"
]
}
},
"user": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7",
"hints": {
"allow": [
"GET"
]
}
}
}
},
{
"id": "sms2e9jimvGguM6zY1t7",
"factorType": "sms",
"provider": "OKTA",
"vendorName": "OKTA",
"status": "ACTIVE",
"created": "2017-05-24T19:53:13.000Z",
"lastUpdated": "2017-05-24T19:53:13.000Z",
"profile": {
"phoneNumber": "+15052694259"
},
"_links": {
"self": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/sms2e9jimvGguM6zY1t7",
"hints": {
"allow": [
"GET",
"DELETE"
]
}
},
"verify": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/sms2e9jimvGguM6zY1t7/verify",
"hints": {
"allow": [
"POST"
]
}
},
"user": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7",
"hints": {
"allow": [
"GET"
]
}
}
}
},
{
"id": "uft8gh35mszUCXKg21t7",
"factorType": "token:software:totp",
"provider": "GOOGLE",
"vendorName": "GOOGLE",
"status": "ACTIVE",
"created": "2018-10-02T21:28:08.000Z",
"lastUpdated": "2018-10-02T21:29:58.000Z",
"profile": {
"credentialId": "jeff.beck@acme.com"
},
"_links": {
"self": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/uft8gh35mszUCXKg21t7",
"hints": {
"allow": [
"GET",
"DELETE"
]
}
},
"verify": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7/factors/uft8gh35mszUCXKg21t7/verify",
"hints": {
"allow": [
"POST"
]
}
},
"user": {
"href": "https://oktalane.okta.com/api/v1/users/00u2e9hju0dCitSuI1t7",
"hints": {
"allow": [
"GET"
]
}
}
}
}
]
This request is typical for registering new users into a custom application. The registration form should collect the user's first and last name, primary email address, and preferred username (email format is not required), as well as the user's password. The activate=true query parameter will cause this user to be created in Okta as in an active status.
curl -X POST \
'https://btgapi.okta.com/api/v1/users?activate=true' \
-H 'Accept: application/json' \
-H 'Authorization: SSWS 0084-m5qg88tdJln8L4b6L94pXmLQmwFSAzWWTg_fu' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: 23972c92-8ea6-480f-a343-a637be6c03d9' \
-d '{
"profile": {
"firstName": "Bruce",
"lastName": "Banner",
"email": "bruce@amce.com",
"login": "bruce@amce.com",
"mobilePhone": "5052694259"
},
"credentials": {
"password" : { "value": "D3m0demo1" }
},
"groupIds": [
"00g11eyizklnBxpN42p7",
"00g11dsz2ebabDtTI2p7"
]
}'
__Note:__The request above includes some attributes, such as mobilePhone and the groupIds array, which represents the Okta internal IDs of groups to which this user will automatically be added. Group membership can, in turn, be used by Okta policies (such as determining which users will be prompted for MFA and when), application assignment, etc.
A successful response looks like this:
{
"id": "00u28o8b4vIBpE4Cd2p7",
"status": "ACTIVE",
"created": "2018-10-04T20:58:17.000Z",
"activated": "2018-10-04T20:58:18.000Z",
"statusChanged": "2018-10-04T20:58:18.000Z",
"lastLogin": null,
"lastUpdated": "2018-10-04T20:58:18.000Z",
"passwordChanged": "2018-10-04T20:58:18.000Z",
"profile": {
"firstName": "Bruce",
"lastName": "Banner",
"mobilePhone": "5052694259",
"secondEmail": null,
"login": "bruce@amce.com",
"email": "bruce@amce.com"
},
"credentials": {
"password": {},
"emails": [
{
"value": "bruce@amce.com",
"status": "VERIFIED",
"type": "PRIMARY"
}
],
"provider": {
"type": "OKTA",
"name": "OKTA"
}
},
"_links": {
"suspend": {
"href": "https://btgapi.okta.com/api/v1/users/00u28o8b4vIBpE4Cd2p7/lifecycle/suspend",
"method": "POST"
},
"resetPassword": {
"href": "https://btgapi.okta.com/api/v1/users/00u28o8b4vIBpE4Cd2p7/lifecycle/reset_password",
"method": "POST"
},
"forgotPassword": {
"href": "https://btgapi.okta.com/api/v1/users/00u28o8b4vIBpE4Cd2p7/credentials/forgot_password",
"method": "POST"
},
"expirePassword": {
"href": "https://btgapi.okta.com/api/v1/users/00u28o8b4vIBpE4Cd2p7/lifecycle/expire_password",
"method": "POST"
},
"changeRecoveryQuestion": {
"href": "https://btgapi.okta.com/api/v1/users/00u28o8b4vIBpE4Cd2p7/credentials/change_recovery_question",
"method": "POST"
},
"self": {
"href": "https://btgapi.okta.com/api/v1/users/00u28o8b4vIBpE4Cd2p7"
},
"changePassword": {
"href": "https://btgapi.okta.com/api/v1/users/00u28o8b4vIBpE4Cd2p7/credentials/change_password",
"method": "POST"
},
"deactivate": {
"href": "https://btgapi.okta.com/api/v1/users/00u28o8b4vIBpE4Cd2p7/lifecycle/deactivate",
"method": "POST"
}
}
}
If your registration form collects the users mobile number, you can auto-enroll that number for SMS Multi-factor Authentication: https://developer.okta.com/docs/api/resources/factors#enroll-and-auto-activate-okta-sms-factor
Documentation for the APIs needed to handle forgotten password, changing password, etc. can be found here: https://developer.okta.com/docs/api/resources/users#credential-operations.