Step 1: Create a custom application
POST {{apiPath}}/environments/{{envID}}/applications
You can use the POST {{apiPath}}/environments/{{envID}}/applications endpoint to create the new application.
The app config must specify the DEVICE_CODE value on the grantTypes property (and optionally the REFRESH_TOKEN value). Applications configured with the device code grant type use the /{{envID}}/as/device_authorization endpoint to initiate authorization.
|
The |
The response data returns information about the new application, including its id property, which identifies the UUID for this application resource. You will need the application’s UUID property value in Step 5 to send the authorization request and in Step 11 for the token request.
Body
raw ( application/json )
{
"enabled": true,
"name": "Device-App{{$timestamp}}",
"description": "App for Device Auth Grant",
"type": "CUSTOM_APP",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"DEVICE_CODE",
"REFRESH_TOKEN"
],
"deviceTimeout": 600,
"devicePollingInterval": 5,
"tokenEndpointAuthMethod": "NONE"
}
Example Request
-
cURL
-
C#
-
Go
-
HTTP
-
Java
-
jQuery
-
NodeJS
-
Python
-
PHP
-
Ruby
-
Swift
curl --location --globoff '{{apiPath}}/environments/{{envID}}/applications' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{accessToken}}' \
--data '{
"enabled": true,
"name": "Device-App{{$timestamp}}",
"description": "App for Device Auth Grant",
"type": "CUSTOM_APP",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"DEVICE_CODE",
"REFRESH_TOKEN"
],
"deviceTimeout": 600,
"devicePollingInterval": 5,
"tokenEndpointAuthMethod": "NONE"
}'
var options = new RestClientOptions("{{apiPath}}/environments/{{envID}}/applications")
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("", Method.Post);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Bearer {{accessToken}}");
var body = @"{" + "\n" +
@" ""enabled"": true," + "\n" +
@" ""name"": ""Device-App{{$timestamp}}""," + "\n" +
@" ""description"": ""App for Device Auth Grant""," + "\n" +
@" ""type"": ""CUSTOM_APP""," + "\n" +
@" ""protocol"": ""OPENID_CONNECT""," + "\n" +
@" ""grantTypes"": [" + "\n" +
@" ""DEVICE_CODE""," + "\n" +
@" ""REFRESH_TOKEN""" + "\n" +
@" ]," + "\n" +
@" ""deviceTimeout"": 600," + "\n" +
@" ""devicePollingInterval"": 5," + "\n" +
@" ""tokenEndpointAuthMethod"": ""NONE""" + "\n" +
@"}";
request.AddStringBody(body, DataFormat.Json);
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "{{apiPath}}/environments/{{envID}}/applications"
method := "POST"
payload := strings.NewReader(`{
"enabled": true,
"name": "Device-App{{$timestamp}}",
"description": "App for Device Auth Grant",
"type": "CUSTOM_APP",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"DEVICE_CODE",
"REFRESH_TOKEN"
],
"deviceTimeout": 600,
"devicePollingInterval": 5,
"tokenEndpointAuthMethod": "NONE"
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Bearer {{accessToken}}")
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))
}
POST /environments/{{envID}}/applications HTTP/1.1
Host: {{apiPath}}
Content-Type: application/json
Authorization: Bearer {{accessToken}}
{
"enabled": true,
"name": "Device-App{{$timestamp}}",
"description": "App for Device Auth Grant",
"type": "CUSTOM_APP",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"DEVICE_CODE",
"REFRESH_TOKEN"
],
"deviceTimeout": 600,
"devicePollingInterval": 5,
"tokenEndpointAuthMethod": "NONE"
}
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"enabled\": true,\n \"name\": \"Device-App{{$timestamp}}\",\n \"description\": \"App for Device Auth Grant\",\n \"type\": \"CUSTOM_APP\",\n \"protocol\": \"OPENID_CONNECT\",\n \"grantTypes\": [\n \"DEVICE_CODE\",\n \"REFRESH_TOKEN\"\n ],\n \"deviceTimeout\": 600,\n \"devicePollingInterval\": 5,\n \"tokenEndpointAuthMethod\": \"NONE\"\n}");
Request request = new Request.Builder()
.url("{{apiPath}}/environments/{{envID}}/applications")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{accessToken}}")
.build();
Response response = client.newCall(request).execute();
var settings = {
"url": "{{apiPath}}/environments/{{envID}}/applications",
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer {{accessToken}}"
},
"data": JSON.stringify({
"enabled": true,
"name": "Device-App{{$timestamp}}",
"description": "App for Device Auth Grant",
"type": "CUSTOM_APP",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"DEVICE_CODE",
"REFRESH_TOKEN"
],
"deviceTimeout": 600,
"devicePollingInterval": 5,
"tokenEndpointAuthMethod": "NONE"
}),
};
$.ajax(settings).done(function (response) {
console.log(response);
});
var request = require('request');
var options = {
'method': 'POST',
'url': '{{apiPath}}/environments/{{envID}}/applications',
'headers': {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{accessToken}}'
},
body: JSON.stringify({
"enabled": true,
"name": "Device-App{{$timestamp}}",
"description": "App for Device Auth Grant",
"type": "CUSTOM_APP",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"DEVICE_CODE",
"REFRESH_TOKEN"
],
"deviceTimeout": 600,
"devicePollingInterval": 5,
"tokenEndpointAuthMethod": "NONE"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "{{apiPath}}/environments/{{envID}}/applications"
payload = json.dumps({
"enabled": True,
"name": "Device-App{{$timestamp}}",
"description": "App for Device Auth Grant",
"type": "CUSTOM_APP",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"DEVICE_CODE",
"REFRESH_TOKEN"
],
"deviceTimeout": 600,
"devicePollingInterval": 5,
"tokenEndpointAuthMethod": "NONE"
})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{accessToken}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('{{apiPath}}/environments/{{envID}}/applications');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
'follow_redirects' => TRUE
));
$request->setHeader(array(
'Content-Type' => 'application/json',
'Authorization' => 'Bearer {{accessToken}}'
));
$request->setBody('{\n "enabled": true,\n "name": "Device-App{{$timestamp}}",\n "description": "App for Device Auth Grant",\n "type": "CUSTOM_APP",\n "protocol": "OPENID_CONNECT",\n "grantTypes": [\n "DEVICE_CODE",\n "REFRESH_TOKEN"\n ],\n "deviceTimeout": 600,\n "devicePollingInterval": 5,\n "tokenEndpointAuthMethod": "NONE"\n}');
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();
}
require "uri"
require "json"
require "net/http"
url = URI("{{apiPath}}/environments/{{envID}}/applications")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer {{accessToken}}"
request.body = JSON.dump({
"enabled": true,
"name": "Device-App{{\$timestamp}}",
"description": "App for Device Auth Grant",
"type": "CUSTOM_APP",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"DEVICE_CODE",
"REFRESH_TOKEN"
],
"deviceTimeout": 600,
"devicePollingInterval": 5,
"tokenEndpointAuthMethod": "NONE"
})
response = http.request(request)
puts response.read_body
let parameters = "{\n \"enabled\": true,\n \"name\": \"Device-App{{$timestamp}}\",\n \"description\": \"App for Device Auth Grant\",\n \"type\": \"CUSTOM_APP\",\n \"protocol\": \"OPENID_CONNECT\",\n \"grantTypes\": [\n \"DEVICE_CODE\",\n \"REFRESH_TOKEN\"\n ],\n \"deviceTimeout\": 600,\n \"devicePollingInterval\": 5,\n \"tokenEndpointAuthMethod\": \"NONE\"\n}"
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string: "{{apiPath}}/environments/{{envID}}/applications")!,timeoutInterval: Double.infinity)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Bearer {{accessToken}}", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
request.httpBody = postData
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
201 Created
{
"_links": {
"self": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications/fa6d9bac-5928-4cdf-8810-f25e4e0af968"
},
"environment": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
},
"attributes": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications/fa6d9bac-5928-4cdf-8810-f25e4e0af968/attributes"
},
"pushCredentials": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications/fa6d9bac-5928-4cdf-8810-f25e4e0af968/pushCredentials"
},
"secret": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications/fa6d9bac-5928-4cdf-8810-f25e4e0af968/secret"
},
"grants": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications/fa6d9bac-5928-4cdf-8810-f25e4e0af968/grants"
}
},
"environment": {
"id": "abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
},
"id": "fa6d9bac-5928-4cdf-8810-f25e4e0af968",
"name": "Device-App1676502708",
"description": "App for Device Auth Grant",
"enabled": true,
"hiddenFromAppPortal": false,
"type": "CUSTOM_APP",
"protocol": "OPENID_CONNECT",
"createdAt": "2023-02-15T23:11:48.152Z",
"updatedAt": "2023-02-15T23:11:48.152Z",
"assignActorRoles": false,
"grantTypes": [
"REFRESH_TOKEN",
"DEVICE_CODE"
],
"tokenEndpointAuthMethod": "NONE",
"pkceEnforcement": "OPTIONAL",
"devicePollingInterval": 5,
"signing": {
"keyRotationPolicy": {
"id": "38c6ccb0-bfd9-4e6b-ace7-4651c52a3c2c"
}
},
"deviceTimeout": 600
}