Update enterprise OAuth connection
Update an enterprise OIDC SSO connection. The config type is immutable,
and the enterprise block’s email_domain_allowlist must stay
non-empty and must not overlap another connection’s.
curl --request PUT \
--url https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"client_id": "123456789.apps.googleusercontent.com",
"type": "enterprise",
"client_secret": "GOCSPX-abc123def456",
"enabled": true,
"scopes": [
"openid"
],
"granted_scopes": [
"prld:pwd:write"
],
"options": {
"use_email_as_identifier": true,
"allow_email_account_merge": false,
"verify_email": false
},
"apple": {
"team_id": "ABCDEF1234",
"key_id": "KEY123456",
"p8_key": "-----BEGIN PRIVATE KEY-----\nMIGT...base64...==\n-----END PRIVATE KEY-----"
},
"okta": {
"issuer_url": "https://dev-123456.okta.com/oauth2/default"
}
}
'import requests
url = "https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}"
payload = {
"client_id": "123456789.apps.googleusercontent.com",
"type": "enterprise",
"client_secret": "GOCSPX-abc123def456",
"enabled": True,
"scopes": ["openid"],
"granted_scopes": ["prld:pwd:write"],
"options": {
"use_email_as_identifier": True,
"allow_email_account_merge": False,
"verify_email": False
},
"apple": {
"team_id": "ABCDEF1234",
"key_id": "KEY123456",
"p8_key": "-----BEGIN PRIVATE KEY-----
MIGT...base64...==
-----END PRIVATE KEY-----"
},
"okta": { "issuer_url": "https://dev-123456.okta.com/oauth2/default" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
client_id: '123456789.apps.googleusercontent.com',
type: 'enterprise',
client_secret: 'GOCSPX-abc123def456',
enabled: true,
scopes: ['openid'],
granted_scopes: ['prld:pwd:write'],
options: {
use_email_as_identifier: true,
allow_email_account_merge: false,
verify_email: false
},
apple: {
team_id: 'ABCDEF1234',
key_id: 'KEY123456',
p8_key: '-----BEGIN PRIVATE KEY-----\nMIGT...base64...==\n-----END PRIVATE KEY-----'
},
okta: {issuer_url: 'https://dev-123456.okta.com/oauth2/default'}
})
};
fetch('https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'client_id' => '123456789.apps.googleusercontent.com',
'type' => 'enterprise',
'client_secret' => 'GOCSPX-abc123def456',
'enabled' => true,
'scopes' => [
'openid'
],
'granted_scopes' => [
'prld:pwd:write'
],
'options' => [
'use_email_as_identifier' => true,
'allow_email_account_merge' => false,
'verify_email' => false
],
'apple' => [
'team_id' => 'ABCDEF1234',
'key_id' => 'KEY123456',
'p8_key' => '-----BEGIN PRIVATE KEY-----
MIGT...base64...==
-----END PRIVATE KEY-----'
],
'okta' => [
'issuer_url' => 'https://dev-123456.okta.com/oauth2/default'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}"
payload := strings.NewReader("{\n \"client_id\": \"123456789.apps.googleusercontent.com\",\n \"type\": \"enterprise\",\n \"client_secret\": \"GOCSPX-abc123def456\",\n \"enabled\": true,\n \"scopes\": [\n \"openid\"\n ],\n \"granted_scopes\": [\n \"prld:pwd:write\"\n ],\n \"options\": {\n \"use_email_as_identifier\": true,\n \"allow_email_account_merge\": false,\n \"verify_email\": false\n },\n \"apple\": {\n \"team_id\": \"ABCDEF1234\",\n \"key_id\": \"KEY123456\",\n \"p8_key\": \"-----BEGIN PRIVATE KEY-----\\nMIGT...base64...==\\n-----END PRIVATE KEY-----\"\n },\n \"okta\": {\n \"issuer_url\": \"https://dev-123456.okta.com/oauth2/default\"\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"client_id\": \"123456789.apps.googleusercontent.com\",\n \"type\": \"enterprise\",\n \"client_secret\": \"GOCSPX-abc123def456\",\n \"enabled\": true,\n \"scopes\": [\n \"openid\"\n ],\n \"granted_scopes\": [\n \"prld:pwd:write\"\n ],\n \"options\": {\n \"use_email_as_identifier\": true,\n \"allow_email_account_merge\": false,\n \"verify_email\": false\n },\n \"apple\": {\n \"team_id\": \"ABCDEF1234\",\n \"key_id\": \"KEY123456\",\n \"p8_key\": \"-----BEGIN PRIVATE KEY-----\\nMIGT...base64...==\\n-----END PRIVATE KEY-----\"\n },\n \"okta\": {\n \"issuer_url\": \"https://dev-123456.okta.com/oauth2/default\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"client_id\": \"123456789.apps.googleusercontent.com\",\n \"type\": \"enterprise\",\n \"client_secret\": \"GOCSPX-abc123def456\",\n \"enabled\": true,\n \"scopes\": [\n \"openid\"\n ],\n \"granted_scopes\": [\n \"prld:pwd:write\"\n ],\n \"options\": {\n \"use_email_as_identifier\": true,\n \"allow_email_account_merge\": false,\n \"verify_email\": false\n },\n \"apple\": {\n \"team_id\": \"ABCDEF1234\",\n \"key_id\": \"KEY123456\",\n \"p8_key\": \"-----BEGIN PRIVATE KEY-----\\nMIGT...base64...==\\n-----END PRIVATE KEY-----\"\n },\n \"okta\": {\n \"issuer_url\": \"https://dev-123456.okta.com/oauth2/default\"\n }\n}"
response = http.request(request)
puts response.read_body{
"config": {
"provider_id": "google",
"type": "enterprise",
"client_id": "123456789.apps.googleusercontent.com",
"enabled": true,
"scopes": [
"openid"
],
"options": {
"use_email_as_identifier": true,
"allow_email_account_merge": false,
"verify_email": false
},
"created_at": "2025-03-15T10:30:00Z",
"updated_at": "2025-03-15T12:00:00Z",
"connection_id": "ocon_01jqebhswje1ka1z7ahr9rfsgt",
"granted_scopes": [
"prld:pwd:write"
],
"apple": {
"team_id": "ABCDEF1234",
"key_id": "KEY123456",
"p8_key": "-----BEGIN PRIVATE KEY-----\nMIGT...base64...==\n-----END PRIVATE KEY-----"
},
"okta": {
"issuer_url": "https://dev-123456.okta.com/oauth2/default"
},
"enterprise": {
"issuer_url": "https://acme.okta.com/oauth2/default",
"email_domain_allowlist": [
"acme.com"
],
"jit_provisioning": true,
"allow_email_account_merge": true,
"enforce_login": false,
"sync_profile_on_login": true,
"default_redirect_uri": "https://acme.yourapp.com/callback",
"claim_mapping": {
"email": "email",
"given_name": "given_name",
"family_name": "family_name",
"custom": {}
}
}
}
}{
"code": "invalid_request",
"status": "bad_request",
"message": "The request body is invalid."
}{
"code": "app_not_found",
"status": "not_found",
"message": "The application was not found."
}{
"code": "oauth_email_domain_conflict",
"status": "conflict",
"message": "An email domain is already claimed by another OAuth connection."
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
The id of the app the request refers to. An application's unique identifier.
"54e9ujn"
"fvua38g"
The OAuth provider identifier.
"google"
"apple"
"github"
"microsoft"
"okta"
"facebook"
"linkedin"
The enterprise OAuth connection identifier (prefixed with ocon_).
"ocon_01jqebhswje1ka1z7ahr9rfsgt"
Body
"123456789.apps.googleusercontent.com"
personal is the classic social-login config (at most one per
provider, addressed as …/oauth/{provider}). enterprise is a
per-connection OIDC SSO config (any number per provider, addressed as
…/oauth/{provider}/{connectionID}). Defaults to personal.
personal, enterprise "enterprise"
"GOCSPX-abc123def456"
true
Scopes requested from the OAuth provider (IdP).
Prelude session scopes attached to the session when a login completes through this social provider (for example prld:pwd:write). Distinct from scopes, which are requested from the IdP.
["prld:pwd:write"]
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Required when type is enterprise. The config type is immutable across updates.
Show child attributes
Show child attributes
Response
OK
Show child attributes
Show child attributes
curl --request PUT \
--url https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"client_id": "123456789.apps.googleusercontent.com",
"type": "enterprise",
"client_secret": "GOCSPX-abc123def456",
"enabled": true,
"scopes": [
"openid"
],
"granted_scopes": [
"prld:pwd:write"
],
"options": {
"use_email_as_identifier": true,
"allow_email_account_merge": false,
"verify_email": false
},
"apple": {
"team_id": "ABCDEF1234",
"key_id": "KEY123456",
"p8_key": "-----BEGIN PRIVATE KEY-----\nMIGT...base64...==\n-----END PRIVATE KEY-----"
},
"okta": {
"issuer_url": "https://dev-123456.okta.com/oauth2/default"
}
}
'import requests
url = "https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}"
payload = {
"client_id": "123456789.apps.googleusercontent.com",
"type": "enterprise",
"client_secret": "GOCSPX-abc123def456",
"enabled": True,
"scopes": ["openid"],
"granted_scopes": ["prld:pwd:write"],
"options": {
"use_email_as_identifier": True,
"allow_email_account_merge": False,
"verify_email": False
},
"apple": {
"team_id": "ABCDEF1234",
"key_id": "KEY123456",
"p8_key": "-----BEGIN PRIVATE KEY-----
MIGT...base64...==
-----END PRIVATE KEY-----"
},
"okta": { "issuer_url": "https://dev-123456.okta.com/oauth2/default" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
client_id: '123456789.apps.googleusercontent.com',
type: 'enterprise',
client_secret: 'GOCSPX-abc123def456',
enabled: true,
scopes: ['openid'],
granted_scopes: ['prld:pwd:write'],
options: {
use_email_as_identifier: true,
allow_email_account_merge: false,
verify_email: false
},
apple: {
team_id: 'ABCDEF1234',
key_id: 'KEY123456',
p8_key: '-----BEGIN PRIVATE KEY-----\nMIGT...base64...==\n-----END PRIVATE KEY-----'
},
okta: {issuer_url: 'https://dev-123456.okta.com/oauth2/default'}
})
};
fetch('https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'client_id' => '123456789.apps.googleusercontent.com',
'type' => 'enterprise',
'client_secret' => 'GOCSPX-abc123def456',
'enabled' => true,
'scopes' => [
'openid'
],
'granted_scopes' => [
'prld:pwd:write'
],
'options' => [
'use_email_as_identifier' => true,
'allow_email_account_merge' => false,
'verify_email' => false
],
'apple' => [
'team_id' => 'ABCDEF1234',
'key_id' => 'KEY123456',
'p8_key' => '-----BEGIN PRIVATE KEY-----
MIGT...base64...==
-----END PRIVATE KEY-----'
],
'okta' => [
'issuer_url' => 'https://dev-123456.okta.com/oauth2/default'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}"
payload := strings.NewReader("{\n \"client_id\": \"123456789.apps.googleusercontent.com\",\n \"type\": \"enterprise\",\n \"client_secret\": \"GOCSPX-abc123def456\",\n \"enabled\": true,\n \"scopes\": [\n \"openid\"\n ],\n \"granted_scopes\": [\n \"prld:pwd:write\"\n ],\n \"options\": {\n \"use_email_as_identifier\": true,\n \"allow_email_account_merge\": false,\n \"verify_email\": false\n },\n \"apple\": {\n \"team_id\": \"ABCDEF1234\",\n \"key_id\": \"KEY123456\",\n \"p8_key\": \"-----BEGIN PRIVATE KEY-----\\nMIGT...base64...==\\n-----END PRIVATE KEY-----\"\n },\n \"okta\": {\n \"issuer_url\": \"https://dev-123456.okta.com/oauth2/default\"\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"client_id\": \"123456789.apps.googleusercontent.com\",\n \"type\": \"enterprise\",\n \"client_secret\": \"GOCSPX-abc123def456\",\n \"enabled\": true,\n \"scopes\": [\n \"openid\"\n ],\n \"granted_scopes\": [\n \"prld:pwd:write\"\n ],\n \"options\": {\n \"use_email_as_identifier\": true,\n \"allow_email_account_merge\": false,\n \"verify_email\": false\n },\n \"apple\": {\n \"team_id\": \"ABCDEF1234\",\n \"key_id\": \"KEY123456\",\n \"p8_key\": \"-----BEGIN PRIVATE KEY-----\\nMIGT...base64...==\\n-----END PRIVATE KEY-----\"\n },\n \"okta\": {\n \"issuer_url\": \"https://dev-123456.okta.com/oauth2/default\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.prelude.dev/v2/session/apps/{appID}/config/login/oauth/{provider}/{connectionID}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"client_id\": \"123456789.apps.googleusercontent.com\",\n \"type\": \"enterprise\",\n \"client_secret\": \"GOCSPX-abc123def456\",\n \"enabled\": true,\n \"scopes\": [\n \"openid\"\n ],\n \"granted_scopes\": [\n \"prld:pwd:write\"\n ],\n \"options\": {\n \"use_email_as_identifier\": true,\n \"allow_email_account_merge\": false,\n \"verify_email\": false\n },\n \"apple\": {\n \"team_id\": \"ABCDEF1234\",\n \"key_id\": \"KEY123456\",\n \"p8_key\": \"-----BEGIN PRIVATE KEY-----\\nMIGT...base64...==\\n-----END PRIVATE KEY-----\"\n },\n \"okta\": {\n \"issuer_url\": \"https://dev-123456.okta.com/oauth2/default\"\n }\n}"
response = http.request(request)
puts response.read_body{
"config": {
"provider_id": "google",
"type": "enterprise",
"client_id": "123456789.apps.googleusercontent.com",
"enabled": true,
"scopes": [
"openid"
],
"options": {
"use_email_as_identifier": true,
"allow_email_account_merge": false,
"verify_email": false
},
"created_at": "2025-03-15T10:30:00Z",
"updated_at": "2025-03-15T12:00:00Z",
"connection_id": "ocon_01jqebhswje1ka1z7ahr9rfsgt",
"granted_scopes": [
"prld:pwd:write"
],
"apple": {
"team_id": "ABCDEF1234",
"key_id": "KEY123456",
"p8_key": "-----BEGIN PRIVATE KEY-----\nMIGT...base64...==\n-----END PRIVATE KEY-----"
},
"okta": {
"issuer_url": "https://dev-123456.okta.com/oauth2/default"
},
"enterprise": {
"issuer_url": "https://acme.okta.com/oauth2/default",
"email_domain_allowlist": [
"acme.com"
],
"jit_provisioning": true,
"allow_email_account_merge": true,
"enforce_login": false,
"sync_profile_on_login": true,
"default_redirect_uri": "https://acme.yourapp.com/callback",
"claim_mapping": {
"email": "email",
"given_name": "given_name",
"family_name": "family_name",
"custom": {}
}
}
}
}{
"code": "invalid_request",
"status": "bad_request",
"message": "The request body is invalid."
}{
"code": "app_not_found",
"status": "not_found",
"message": "The application was not found."
}{
"code": "oauth_email_domain_conflict",
"status": "conflict",
"message": "An email domain is already claimed by another OAuth connection."
}