Step 3: Create an environment
POST {{apiPath}}/environments
Use the POST {{apiPath}}/environments request to create a new environment. You need to have the Organization Admin role to create an environment. You’re automatically assigned the Organization Admin role when you create a PingOne account.
When your organization includes more than one PingOne license, you must include the following JSON with a valid license ID in the request body.
"license": {
"id": "{{licenseID}}"
}
The new environment will include several PingOne resources automatically created for a new environment (such as, a default sign-on policy, password policy, a default population, and defined notifications templates). This workflow uses the environment’s default sign-on policy and password policy to simplify the workflow.
In this request:
-
{{apiPath}}is the geographic regional domain for the PingOne API endpoints for your PingOne environment. The PingOne top-level domain ishttps://api.pingone.com/v1for the U.S. Refer to PingOne API domains for the top-level domains for other regions.
In the request body:
-
nameis required, and is a String containing the name to assign to the environment. -
descriptionis optional, and describes the purpose of the environment. -
typecan be eitherSANDBOXorPRODUCTION. In this case, useSANDBOX.
When successful, the response returns a Status: 201 created message, and shows the new environment’s configuration data.
The response includes an id property value (a UUID) for your new environment. If you’re using Postman, the script in the Script tab sets {{envID}} to this value. Every request in this workflow uses {{envID}} in the request URL to specify the PingOne resources associated with your environment.
It’s useful to sign on to the PingOne admin console, and see your new environment shown. Note that there is no associated population, which you’ll create in the next step.
Troubleshooting
-
Verify that you’re using Bearer authorization for this request (and all
{{apiPath}}requests), and you have a valid access token.For Postman users, check that the Authorization tab in Postman is set to Bearer Token, and the access token variable is assigned (shown in blue, not red). The Postman script (in the Scripts tab) in the previous set to get an access token should have set the access token. Note that if Bearer Token and the access token is set correctly here, our Postman scripts will carry these settings forward to the remaining steps in this workflow.
-
Verify that you’ve assigned the Organization Admin role to your Worker app. Refer to Assign roles to the Worker app.
-
If you get a 401 Unauthorized message, this is likely due to the access token expiring (a 1 hour expiry time). Refer to the step to get an access token, and call this request again.
-
Verify that
{{apiPath}}is correct for your geographic region.
Example Request
-
cURL
-
C#
-
Go
-
HTTP
-
Java
-
jQuery
-
NodeJS
-
Python
-
PHP
-
Ruby
-
Swift
curl --location --globoff '{{apiPath}}/environments' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{accessToken}}' \
--data '{
"name": "New-Solution-Env_{{$timestamp}}",
"description": "New environment description",
"type": "SANDBOX",
"region": "NA",
"license": {
"id": "{{licenseID}}"
}
}'
var options = new RestClientOptions("{{apiPath}}/environments")
{
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" +
@" ""name"": ""New-Solution-Env_{{$timestamp}}""," + "\n" +
@" ""description"": ""New environment description""," + "\n" +
@" ""type"": ""SANDBOX""," + "\n" +
@" ""region"": ""NA""," + "\n" +
@" ""license"": {" + "\n" +
@" ""id"": ""{{licenseID}}""" + "\n" +
@" }" + "\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"
method := "POST"
payload := strings.NewReader(`{
"name": "New-Solution-Env_{{$timestamp}}",
"description": "New environment description",
"type": "SANDBOX",
"region": "NA",
"license": {
"id": "{{licenseID}}"
}
}`)
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 HTTP/1.1
Host: {{apiPath}}
Content-Type: application/json
Authorization: Bearer {{accessToken}}
{
"name": "New-Solution-Env_{{$timestamp}}",
"description": "New environment description",
"type": "SANDBOX",
"region": "NA",
"license": {
"id": "{{licenseID}}"
}
}
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"name\": \"New-Solution-Env_{{$timestamp}}\",\n \"description\": \"New environment description\",\n \"type\": \"SANDBOX\",\n \"region\": \"NA\",\n \"license\": {\n \"id\": \"{{licenseID}}\"\n }\n}");
Request request = new Request.Builder()
.url("{{apiPath}}/environments")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{accessToken}}")
.build();
Response response = client.newCall(request).execute();
var settings = {
"url": "{{apiPath}}/environments",
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer {{accessToken}}"
},
"data": JSON.stringify({
"name": "New-Solution-Env_{{$timestamp}}",
"description": "New environment description",
"type": "SANDBOX",
"region": "NA",
"license": {
"id": "{{licenseID}}"
}
}),
};
$.ajax(settings).done(function (response) {
console.log(response);
});
var request = require('request');
var options = {
'method': 'POST',
'url': '{{apiPath}}/environments',
'headers': {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{accessToken}}'
},
body: JSON.stringify({
"name": "New-Solution-Env_{{$timestamp}}",
"description": "New environment description",
"type": "SANDBOX",
"region": "NA",
"license": {
"id": "{{licenseID}}"
}
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "{{apiPath}}/environments"
payload = json.dumps({
"name": "New-Solution-Env_{{$timestamp}}",
"description": "New environment description",
"type": "SANDBOX",
"region": "NA",
"license": {
"id": "{{licenseID}}"
}
})
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');
$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 "name": "New-Solution-Env_{{$timestamp}}",\n "description": "New environment description",\n "type": "SANDBOX",\n "region": "NA",\n "license": {\n "id": "{{licenseID}}"\n }\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")
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({
"name": "New-Solution-Env_{{\$timestamp}}",
"description": "New environment description",
"type": "SANDBOX",
"region": "NA",
"license": {
"id": "{{licenseID}}"
}
})
response = http.request(request)
puts response.read_body
let parameters = "{\n \"name\": \"New-Solution-Env_{{$timestamp}}\",\n \"description\": \"New environment description\",\n \"type\": \"SANDBOX\",\n \"region\": \"NA\",\n \"license\": {\n \"id\": \"{{licenseID}}\"\n }\n}"
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string: "{{apiPath}}/environments")!,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"
},
"organization": {
"href": "https://api.pingone.com/v1/organizations/bed432e6-676a-4ebe-b5a5-6b3b54e46bda"
},
"license": {
"href": "https://api.pingone.com/v1/organizations/bed432e6-676a-4ebe-b5a5-6b3b54e46bda/licenses/57f0efac-37d9-4a17-8a35-196bb3362983"
},
"populations": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/populations"
},
"users": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users"
},
"applications": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications"
},
"activities": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/activities"
},
"branding": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/branding"
},
"resources": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/resources"
},
"passwordPolicies": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/passwordPolicies"
},
"userActivities": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/userActivities"
},
"signOnPolicies": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/signOnPolicies"
},
"keys": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/keys"
},
"templates": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/templates"
},
"notificationsSettings": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/notificationsSettings"
},
"schemas": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/schemas"
},
"gateways": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/gateways"
},
"capabilities": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/capabilities"
},
"activeIdentityCounts": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/activeIdentityCounts"
},
"propagation/plans": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/propagation/plans"
},
"propagation/stores": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/propagation/stores"
},
"propagation/revisions/id:latest": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/propagation/revisions/id:latest"
},
"billOfMaterials": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/billOfMaterials"
}
},
"id": "abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6",
"name": "New-Solution-Env_1680720342",
"description": "New environment description",
"organization": {
"id": "bed432e6-676a-4ebe-b5a5-6b3b54e46bda"
},
"type": "SANDBOX",
"region": "NA",
"createdAt": "2023-04-05T18:45:41.822Z",
"updatedAt": "2023-04-05T18:45:41.822Z",
"license": {
"id": "57f0efac-37d9-4a17-8a35-196bb3362983"
},
"billOfMaterials": {
"products": [
{
"id": "f27354d1-3604-45b6-a9ca-117b04465db5",
"type": "PING_ONE_BASE",
"description": "PingOne Base"
},
{
"id": "2d367bc0-1bbb-436a-994d-3079d106a481",
"type": "PING_ONE_MFA",
"description": "PingOne MFA"
},
{
"id": "b6d91834-94a2-44f8-924a-5757cf9f70b3",
"type": "PING_ONE_RISK",
"description": "PingOne Risk"
},
{
"id": "f1e950d2-babf-4599-b0f4-0e11d0cefa30",
"type": "PING_ONE_PROVISIONING",
"description": "PingOne Provisioning"
},
{
"id": "8af7b167-e802-41de-b940-20740d0e7202",
"type": "PING_ONE_VERIFY",
"description": "PingOne Verify"
},
{
"id": "b332968c-6f93-4432-81b0-be36d954934a",
"type": "PING_ONE_AUTHORIZE",
"description": "PingOne Authorize"
},
{
"id": "86b9e37a-eaa9-4d4e-be03-321489636c01",
"type": "PING_ONE_DAVINCI",
"description": "PingOne DaVinci"
}
],
"createdAt": "2023-04-05T18:45:41.845Z",
"updatedAt": "2023-04-05T18:45:41.845Z"
}
}