Create Linked Account
POST {{apiPath}}/environments/{{envID}}/users/{{userID}}/linkedAccounts
The POST {{apiPath}}/environments/{{envID}}/users/{{userID}}/linkedAccounts operation creates a linked account to an external identity provider for the user resource with the ID specified in the request URL.
This operation uses the application/vnd.pingidentity.account.link+json custom content type in the request header, and it must specify the identityProvider.Id and the externalId for the user account in the request body. The request body can also specify an optional list of user attributes to update during the account linking action.
Prerequisites
-
Refer to User Operations for important overview information.
-
Create a user to get a
userIDandusername. Refer to Create User. Run Read User or Users to find an existing user. -
Refer to Identity Providers for more information about adding an identity provider for the
idpIDvalue. Run Read All Identity Providers to find an existing IdP.
Request Model
| Property | Type | Required? |
|---|---|---|
|
String |
Required |
|
String |
Required |
Refer to the Linked Accounts data model for full property descriptions.
Headers
Authorization Bearer {{accessToken}}
Content-Type application/vnd.pingidentity.account.link+json
Body
raw ( application/vnd.pingidentity.account.link+json )
{
"identityProvider": {
"id": "{{idpID}}"
},
"externalId": "3249023841",
"attributes": {
"username": {
"value": "{{username}}",
"update": "EMPTY_ONLY"
},
"email": {
"value": "{{email}}",
"update": "EMPTY_ONLY"
},
"name.first": {
"value": "leslie",
"update": "ALWAYS"
},
"name.last": {
"value": "Jones",
"update": "EMPTY_ONLY"
}
}
}
Example Request
-
cURL
-
C#
-
Go
-
HTTP
-
Java
-
jQuery
-
NodeJS
-
Python
-
PHP
-
Ruby
-
Swift
curl --location --globoff '{{apiPath}}/environments/{{envID}}/users/{{userID}}/linkedAccounts' \
--header 'Content-Type: application/vnd.pingidentity.account.link+json' \
--header 'Authorization: Bearer {{accessToken}}' \
--data '{
"identityProvider": {
"id": "{{idpID}}"
},
"externalId": "3249023841",
"attributes": {
"username": {
"value": "{{username}}",
"update": "EMPTY_ONLY"
},
"email": {
"value": "{{email}}",
"update": "EMPTY_ONLY"
},
"name.first": {
"value": "leslie",
"update": "ALWAYS"
},
"name.last": {
"value": "Jones",
"update": "EMPTY_ONLY"
}
}
}'
var options = new RestClientOptions("{{apiPath}}/environments/{{envID}}/users/{{userID}}/linkedAccounts")
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("", Method.Post);
request.AddHeader("Content-Type", "application/vnd.pingidentity.account.link+json");
request.AddHeader("Authorization", "Bearer {{accessToken}}");
var body = @"{" + "\n" +
@" ""identityProvider"": {" + "\n" +
@" ""id"": ""{{idpID}}""" + "\n" +
@" }," + "\n" +
@" ""externalId"": ""3249023841""," + "\n" +
@" ""attributes"": {" + "\n" +
@" ""username"": {" + "\n" +
@" ""value"": ""{{username}}""," + "\n" +
@" ""update"": ""EMPTY_ONLY""" + "\n" +
@" }," + "\n" +
@" ""email"": {" + "\n" +
@" ""value"": ""{{email}}""," + "\n" +
@" ""update"": ""EMPTY_ONLY""" + "\n" +
@" }," + "\n" +
@" ""name.first"": {" + "\n" +
@" ""value"": ""leslie""," + "\n" +
@" ""update"": ""ALWAYS""" + "\n" +
@" }," + "\n" +
@" ""name.last"": {" + "\n" +
@" ""value"": ""Jones""," + "\n" +
@" ""update"": ""EMPTY_ONLY""" + "\n" +
@" }" + "\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/{{envID}}/users/{{userID}}/linkedAccounts"
method := "POST"
payload := strings.NewReader(`{
"identityProvider": {
"id": "{{idpID}}"
},
"externalId": "3249023841",
"attributes": {
"username": {
"value": "{{username}}",
"update": "EMPTY_ONLY"
},
"email": {
"value": "{{email}}",
"update": "EMPTY_ONLY"
},
"name.first": {
"value": "leslie",
"update": "ALWAYS"
},
"name.last": {
"value": "Jones",
"update": "EMPTY_ONLY"
}
}
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Content-Type", "application/vnd.pingidentity.account.link+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}}/users/{{userID}}/linkedAccounts HTTP/1.1
Host: {{apiPath}}
Content-Type: application/vnd.pingidentity.account.link+json
Authorization: Bearer {{accessToken}}
{
"identityProvider": {
"id": "{{idpID}}"
},
"externalId": "3249023841",
"attributes": {
"username": {
"value": "{{username}}",
"update": "EMPTY_ONLY"
},
"email": {
"value": "{{email}}",
"update": "EMPTY_ONLY"
},
"name.first": {
"value": "leslie",
"update": "ALWAYS"
},
"name.last": {
"value": "Jones",
"update": "EMPTY_ONLY"
}
}
}
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/vnd.pingidentity.account.link+json");
RequestBody body = RequestBody.create(mediaType, "{\n \"identityProvider\": {\n \"id\": \"{{idpID}}\"\n },\n \"externalId\": \"3249023841\",\n \"attributes\": {\n \"username\": {\n \"value\": \"{{username}}\",\n \"update\": \"EMPTY_ONLY\"\n },\n \"email\": {\n \"value\": \"{{email}}\",\n \"update\": \"EMPTY_ONLY\"\n },\n \"name.first\": {\n \"value\": \"leslie\",\n \"update\": \"ALWAYS\"\n },\n \"name.last\": {\n \"value\": \"Jones\",\n \"update\": \"EMPTY_ONLY\"\n }\n }\n}");
Request request = new Request.Builder()
.url("{{apiPath}}/environments/{{envID}}/users/{{userID}}/linkedAccounts")
.method("POST", body)
.addHeader("Content-Type", "application/vnd.pingidentity.account.link+json")
.addHeader("Authorization", "Bearer {{accessToken}}")
.build();
Response response = client.newCall(request).execute();
var settings = {
"url": "{{apiPath}}/environments/{{envID}}/users/{{userID}}/linkedAccounts",
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/vnd.pingidentity.account.link+json",
"Authorization": "Bearer {{accessToken}}"
},
"data": JSON.stringify({
"identityProvider": {
"id": "{{idpID}}"
},
"externalId": "3249023841",
"attributes": {
"username": {
"value": "{{username}}",
"update": "EMPTY_ONLY"
},
"email": {
"value": "{{email}}",
"update": "EMPTY_ONLY"
},
"name.first": {
"value": "leslie",
"update": "ALWAYS"
},
"name.last": {
"value": "Jones",
"update": "EMPTY_ONLY"
}
}
}),
};
$.ajax(settings).done(function (response) {
console.log(response);
});
var request = require('request');
var options = {
'method': 'POST',
'url': '{{apiPath}}/environments/{{envID}}/users/{{userID}}/linkedAccounts',
'headers': {
'Content-Type': 'application/vnd.pingidentity.account.link+json',
'Authorization': 'Bearer {{accessToken}}'
},
body: JSON.stringify({
"identityProvider": {
"id": "{{idpID}}"
},
"externalId": "3249023841",
"attributes": {
"username": {
"value": "{{username}}",
"update": "EMPTY_ONLY"
},
"email": {
"value": "{{email}}",
"update": "EMPTY_ONLY"
},
"name.first": {
"value": "leslie",
"update": "ALWAYS"
},
"name.last": {
"value": "Jones",
"update": "EMPTY_ONLY"
}
}
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "{{apiPath}}/environments/{{envID}}/users/{{userID}}/linkedAccounts"
payload = json.dumps({
"identityProvider": {
"id": "{{idpID}}"
},
"externalId": "3249023841",
"attributes": {
"username": {
"value": "{{username}}",
"update": "EMPTY_ONLY"
},
"email": {
"value": "{{email}}",
"update": "EMPTY_ONLY"
},
"name.first": {
"value": "leslie",
"update": "ALWAYS"
},
"name.last": {
"value": "Jones",
"update": "EMPTY_ONLY"
}
}
})
headers = {
'Content-Type': 'application/vnd.pingidentity.account.link+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}}/users/{{userID}}/linkedAccounts');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
'follow_redirects' => TRUE
));
$request->setHeader(array(
'Content-Type' => 'application/vnd.pingidentity.account.link+json',
'Authorization' => 'Bearer {{accessToken}}'
));
$request->setBody('{\n "identityProvider": {\n "id": "{{idpID}}"\n },\n "externalId": "3249023841",\n "attributes": {\n "username": {\n "value": "{{username}}",\n "update": "EMPTY_ONLY"\n },\n "email": {\n "value": "{{email}}",\n "update": "EMPTY_ONLY"\n },\n "name.first": {\n "value": "leslie",\n "update": "ALWAYS"\n },\n "name.last": {\n "value": "Jones",\n "update": "EMPTY_ONLY"\n }\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/{{envID}}/users/{{userID}}/linkedAccounts")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/vnd.pingidentity.account.link+json"
request["Authorization"] = "Bearer {{accessToken}}"
request.body = JSON.dump({
"identityProvider": {
"id": "{{idpID}}"
},
"externalId": "3249023841",
"attributes": {
"username": {
"value": "{{username}}",
"update": "EMPTY_ONLY"
},
"email": {
"value": "{{email}}",
"update": "EMPTY_ONLY"
},
"name.first": {
"value": "leslie",
"update": "ALWAYS"
},
"name.last": {
"value": "Jones",
"update": "EMPTY_ONLY"
}
}
})
response = http.request(request)
puts response.read_body
let parameters = "{\n \"identityProvider\": {\n \"id\": \"{{idpID}}\"\n },\n \"externalId\": \"3249023841\",\n \"attributes\": {\n \"username\": {\n \"value\": \"{{username}}\",\n \"update\": \"EMPTY_ONLY\"\n },\n \"email\": {\n \"value\": \"{{email}}\",\n \"update\": \"EMPTY_ONLY\"\n },\n \"name.first\": {\n \"value\": \"leslie\",\n \"update\": \"ALWAYS\"\n },\n \"name.last\": {\n \"value\": \"Jones\",\n \"update\": \"EMPTY_ONLY\"\n }\n }\n}"
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string: "{{apiPath}}/environments/{{envID}}/users/{{userID}}/linkedAccounts")!,timeoutInterval: Double.infinity)
request.addValue("application/vnd.pingidentity.account.link+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
200 OK
{
"_links": {
"self": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/788d4931-6936-43f2-82ff-178f5762298a/linkedAccounts/21fc98ed-5d1c-4fe4-b91e-acde99ce35a9"
},
"environment": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
},
"user": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/users/788d4931-6936-43f2-82ff-178f5762298a"
}
},
"_embedded": {
"user": {
"_embedded": {
"password": {
"status": "PASSWORD_EXPIRED"
},
"population": {
"id": "f22842c9-f1eb-41a5-8072-20041b609cf1"
}
},
"id": "788d4931-6936-43f2-82ff-178f5762298a",
"environment": {
"id": "abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
},
"account": {
"canAuthenticate": true,
"status": "OK"
},
"accountId": "5",
"address": {
"streetAddress": "123 Fake Street",
"locality": "Springfield",
"region": "Somewhere",
"postalCode": "78701",
"countryCode": "US"
},
"createdAt": "2021-03-02T18:19:26.564Z",
"email": "test@test.com",
"enabled": true,
"identityProvider": {
"type": "PING_ONE"
},
"lastSignOn": {
"at": "2021-03-31T19:37:12.129Z",
"remoteIp": "174.21.110.237"
},
"lifecycle": {
"status": "ACCOUNT_OK"
},
"locale": "en-gb",
"mfaEnabled": true,
"mobilePhone": "+1.4445552222",
"name": {
"formatted": "Leslie Jones",
"given": "Leslie",
"middle": "L",
"family": "Jones",
"honorificPrefix": "Dr.",
"honorificSuffix": "IV"
},
"nickname": "Les",
"population": {
"id": "f22842c9-f1eb-41a5-8072-20041b609cf1"
},
"preferredLanguage": "en-gb;q=0.8, en;q=0.7",
"primaryPhone": "+1.2225554444",
"timezone": "America/Los_Angeles",
"title": "Senior Manager",
"type": "tele",
"updatedAt": "2022-02-09T23:52:15.936Z",
"username": "lesliejones@example.com",
"verifyStatus": "NOT_INITIATED"
}
},
"id": "21fc98ed-5d1c-4fe4-b91e-acde99ce35a9",
"environment": {
"id": "abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
},
"user": {
"id": "788d4931-6936-43f2-82ff-178f5762298a"
},
"identityProvider": {
"id": "302990c0-289d-40ec-a2ff-e7c7fd0cca63"
},
"externalId": "3249023841"
}