---
title: Authorize (Non-redirect and MFA Only Flows)
description: For browerless use cases such as native mobile apps where the app wants to render the end user interface, setting the response_mode property to pi.flow allows the app to authenticate using the flows API without needing to handle HTTP redirections. When authentication is complete, the app receives the auth code, access token, or ID token in a JSON response instead of a redirect.
component: pingone-api
page_id: pingone-api:auth:openid-connect-oauth-2/authorize-browserless-and-mfa-only-flows
canonical_url: https://developer.pingidentity.com/pingone-api/auth/openid-connect-oauth-2/authorize-browserless-and-mfa-only-flows.html
section_ids:
  preqrequisites: Preqrequisites
  non-redirect-mfa-flow-example: Non-redirect MFA flow example
  example-request: Example Request
  example-response: Example Response
---

# Authorize (Non-redirect and MFA Only Flows)

##

```none
GET {{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}
```

For browerless use cases such as native mobile apps where the app wants to render the end user interface, setting the `response_mode` property to `pi.flow` allows the app to authenticate using the flows API without needing to handle HTTP redirections. When authentication is complete, the app receives the auth code, access token, or ID token in a JSON response instead of a redirect.

The `response_mode` property is the mechanism for returning authorization response parameters from the authorization endpoint. Options are `query`, `fragment`, `form_post`, and `pi.flow`. The `pi.flow` option is a Ping Identity custom response mode to specify that the `redirect_uri` parameter is not required and authorization response parameters are encoded as a JSON object wrapped in a flow response and returned directly to the client with a `200` status. For more information about the `query`, `fragment`, and `form_post` options, refer to the [ResponseModes](https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes) section of the *OAuth 2.0 Multiple Response Type Encoding Practices* specification. For non-redirect use case information, refer to [Redirect and non-redirect authentication flows](../auth-config-options/browserless-authentication-flow-options.html).

|   |                                                                                                                                                                                   |
| - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | For additional non-redirect use case information, refer to [Redirect and non-redirect authentication flows](../auth-config-options/browserless-authentication-flow-options.html). |

The sample shows the `GET /{{envID}}/as/authorize` operation, which includes the `response_mode` parameter to designate one of the following special authentication flow options:

* A non-redirect flow for mobile clients that implements custom flow interfaces with PingOne platform flow APIs but with native application interface components.

* An integration of PingOne authentication APIs and PingFederate (backend only integration). PingFederate's authentication policy and HTML form adapter handles the initial authentication, and PingOne supplies the multi-factor authentication by providing a `login_hint_token` in the authorization request.

* An MFA only flow where PingFederate performs the initial authentication, and sends the authenticated user to PingOne to complete the MFA workflow. PingFederate returns the `login_hint_token` in a My Account application link to PingOne. The application uses this link to redirect to My Account in PingOne for multi-factor authentication.

  |   |                                                                                                                                                                                                                                                                                                                                                             |
  | - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | In this case, from a PingOne perspective, PingFederate and the application accessing My Account in PingOne will use different user sessions. This means that any user session context (such as, last MFA time) will not be shared between PingFederate and PingOne. So, the application accessing My Account, and the end user may need to re-authenticate. |

### Preqrequisites

* To build the `login_hint_token` JWT, refer to [Create a login\_hint\_token JWT](../auth-config-options/create-a-login_hint_token-jwt.html).

* To build the `request` JWT, refer to [Create a request property JWT](../auth-config-options/create-a-request-property-jwt.html).

> **Collapse: Query parameters**
>
> | Property                | Type   | Required? |
> | ----------------------- | ------ | --------- |
> | `acr_values`            | String | Optional  |
> | `client_id`             | String | Required  |
> | `code_challenge_method` | String | Optional  |
> | `login_hint`            | String | Optional  |
> | `login_hint_token`      | String | Optional  |
> | `mobilePayload`         | String | Optional  |
> | `max_age`               | String | Optional  |
> | `nonce`                 | String | Optional  |
> | `prompt`                | String | Optional  |
> | `redirect_uri`          | String | Required  |
> | `request`               | String | Optional  |
> | `response_mode`         | String | Optional  |
> | `response_type`         | String | Required  |
> | `scope`                 | String | Optional  |
> | `state`                 | String | Optional  |

### Non-redirect MFA flow example

Using both the `login_hint_token` and `request` properties, you can set up a non-redirect MFA flow that can evaluate a user's IP address to determine whether an MFA action is required. In this use case, the authorize request looks like this:

```none
https://auth.pingone.com/{{envID}}/as/authorize?acr_values=MFA-Only&response_type=token id_token&client_id={{clientID}}&response_mode=pi.flow&scope=openid profile email&state={{state}}&login_hint_token={{loginHintTokenJWT}}&request={{requestJWT}}
```

The `acr_values` property identifies an MFA sign-on policy name that includes the appropriate IP-based rules.

The `login_hint_token` property value is a JWT that includes the following claims:

```none
{
"iss": "{{issuerApplicationID}}",
"aud": "https://auth.pingone.com/{{envID}}/as",
"sub": "{{authenticatedUserID}}"
}
```

The `request` property value is a JWT that includes the following claims:

```none
{
"iss": "{{issuerApplicationID}}",
"aud": "https://auth.pingone.com/{{envID}}/as",
"pi.remoteIp": "{{ipAddress}}"
}
```

The `request` token passes in the user's IP address securely.

|   |                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | For details on how to construct the `request` property JWT, refer to [Create a request property JWT](../auth-config-options/create-a-request-property-jwt.html). For information on `pi.template` refer to [Notifications Templates](../../platform/notifications/notifications-templates.html). For information on `pi.clientContext` refer to [Device Authentication](../../mfa/mfa-authentication/mfa-device-authentications.html). |

##

### Example Request

* cURL

* C#

* Go

* HTTP

* Java

* jQuery

* NodeJS

* Python

* PHP

* Ruby

* Swift

```shell
curl --location --globoff '{{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}'
```

```csharp
var options = new RestClientOptions("{{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}")
{
  MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("", Method.Get);
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
```

```golang
package main

import (
  "fmt"
  "net/http"
  "io"
)

func main() {

  url := "{{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}"
  method := "GET"

  client := &http.Client {
  }
  req, err := http.NewRequest(method, url, nil)

  if err != nil {
    fmt.Println(err)
    return
  }
  res, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer res.Body.Close()

  body, err := io.ReadAll(res.Body)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(string(body))
}
```

```http
GET /{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}} HTTP/1.1
Host: {{authPath}}
```

```java
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = RequestBody.create(mediaType, "");
Request request = new Request.Builder()
  .url("{{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}")
  .method("GET", body)
  .build();
Response response = client.newCall(request).execute();
```

```javascript
var settings = {
  "url": "{{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}",
  "method": "GET",
  "timeout": 0,
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
```

```javascript
var request = require('request');
var options = {
  'method': 'GET',
  'url': '{{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}',
  'headers': {
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
```

```python
import requests

url = "{{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}"

payload = {}
headers = {}

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)
```

```php
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('{{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}');
$request->setMethod(HTTP_Request2::METHOD_GET);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
try {
  $response = $request->send();
  if ($response->getStatus() == 200) {
    echo $response->getBody();
  }
  else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
    $response->getReasonPhrase();
  }
}
catch(HTTP_Request2_Exception $e) {
  echo 'Error: ' . $e->getMessage();
}
```

```ruby
require "uri"
require "net/http"

url = URI("{{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}")

http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```swift
var request = URLRequest(url: URL(string: "{{authPath}}/{{envID}}/as/authorize?state={{state}}&response_type=token%20id_token&response_mode=pi.flow&scope=openid%20profile%20email&login_hint_token={{loginHintJwt}}&client_id={{clientID}}")!,timeoutInterval: Double.infinity)
request.httpMethod = "GET"

let task = URLSession.shared.dataTask(with: request) { data, response, error in
  guard let data = data else {
    print(String(describing: error))
    return
  }
  print(String(data: data, encoding: .utf8)!)
}

task.resume()
```

### Example Response

200 OK

```json
{
    "_links": {
        "otp.check": {
            "href": "https://auth.pingone.com/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/flows/03101bf2-7eed-41ca-a326-1f47061eb434"
        },
        "device.select": {
            "href": "https://auth.pingone.com/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/flows/03101bf2-7eed-41ca-a326-1f47061eb434"
        },
        "self": {
            "href": "https://auth.pingone.com/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/flows/03101bf2-7eed-41ca-a326-1f47061eb434"
        },
        "signOnPage": {
            "href": "https://apps.pingone.com/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/signon/?flowId=03101bf2-7eed-41ca-a326-1f47061eb434"
        }
    },
    "_embedded": {
        "devices": [
            {
                "id": "3d9dd925-6aef-4267-a9f6-2e7824c18d33",
                "type": "SMS",
                "status": "ACTIVE",
                "userRetries": 0,
                "phone": "*******01"
            }
        ],
        "application": {
            "name": "WebAppWithMFA_1626821450"
        }
    },
    "id": "03101bf2-7eed-41ca-a326-1f47061eb434",
    "environment": {
        "id": "abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
    },
    "resumeUrl": "https://auth.pingone.com/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/as/resume?flowId=03101bf2-7eed-41ca-a326-1f47061eb434",
    "status": "OTP_REQUIRED",
    "createdAt": "2021-07-20T22:51:31.743Z",
    "expiresAt": "2021-07-20T23:06:32.005Z",
    "bypassAllowed": false,
    "selectedDevice": {
        "id": "3d9dd925-6aef-4267-a9f6-2e7824c18d33"
    }
}
```
