curl --request PUT \
--url https://control.api.niadra.com/v1/sso \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"protocol": "oidc",
"domains": [
"acme.example"
],
"enabled": true,
"enforced": false,
"default_role": null,
"role_mappings": [
{
"group": "niadra-admins",
"role": "admin"
},
{
"group": "cx-quality",
"role": "review"
}
],
"groups_attribute": "groups",
"require_second_factor": false,
"oidc": {
"issuer": "https://login.acme.example",
"client_id": "niadra-console",
"client_secret": "the-client-secret-from-the-provider",
"scopes": [
"groups"
]
},
"reason": "The Console signs in with the company login"
}
'import requests
url = "https://control.api.niadra.com/v1/sso"
payload = {
"protocol": "oidc",
"domains": ["acme.example"],
"enabled": True,
"enforced": False,
"default_role": None,
"role_mappings": [
{
"group": "niadra-admins",
"role": "admin"
},
{
"group": "cx-quality",
"role": "review"
}
],
"groups_attribute": "groups",
"require_second_factor": False,
"oidc": {
"issuer": "https://login.acme.example",
"client_id": "niadra-console",
"client_secret": "the-client-secret-from-the-provider",
"scopes": ["groups"]
},
"reason": "The Console signs in with the company login"
}
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({
protocol: 'oidc',
domains: ['acme.example'],
enabled: true,
enforced: false,
default_role: null,
role_mappings: [{group: 'niadra-admins', role: 'admin'}, {group: 'cx-quality', role: 'review'}],
groups_attribute: 'groups',
require_second_factor: false,
oidc: {
issuer: 'https://login.acme.example',
client_id: 'niadra-console',
client_secret: 'the-client-secret-from-the-provider',
scopes: ['groups']
},
reason: 'The Console signs in with the company login'
})
};
fetch('https://control.api.niadra.com/v1/sso', 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://control.api.niadra.com/v1/sso",
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([
'protocol' => 'oidc',
'domains' => [
'acme.example'
],
'enabled' => true,
'enforced' => false,
'default_role' => null,
'role_mappings' => [
[
'group' => 'niadra-admins',
'role' => 'admin'
],
[
'group' => 'cx-quality',
'role' => 'review'
]
],
'groups_attribute' => 'groups',
'require_second_factor' => false,
'oidc' => [
'issuer' => 'https://login.acme.example',
'client_id' => 'niadra-console',
'client_secret' => 'the-client-secret-from-the-provider',
'scopes' => [
'groups'
]
],
'reason' => 'The Console signs in with the company login'
]),
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://control.api.niadra.com/v1/sso"
payload := strings.NewReader("{\n \"protocol\": \"oidc\",\n \"domains\": [\n \"acme.example\"\n ],\n \"enabled\": true,\n \"enforced\": false,\n \"default_role\": null,\n \"role_mappings\": [\n {\n \"group\": \"niadra-admins\",\n \"role\": \"admin\"\n },\n {\n \"group\": \"cx-quality\",\n \"role\": \"review\"\n }\n ],\n \"groups_attribute\": \"groups\",\n \"require_second_factor\": false,\n \"oidc\": {\n \"issuer\": \"https://login.acme.example\",\n \"client_id\": \"niadra-console\",\n \"client_secret\": \"the-client-secret-from-the-provider\",\n \"scopes\": [\n \"groups\"\n ]\n },\n \"reason\": \"The Console signs in with the company login\"\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://control.api.niadra.com/v1/sso")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"protocol\": \"oidc\",\n \"domains\": [\n \"acme.example\"\n ],\n \"enabled\": true,\n \"enforced\": false,\n \"default_role\": null,\n \"role_mappings\": [\n {\n \"group\": \"niadra-admins\",\n \"role\": \"admin\"\n },\n {\n \"group\": \"cx-quality\",\n \"role\": \"review\"\n }\n ],\n \"groups_attribute\": \"groups\",\n \"require_second_factor\": false,\n \"oidc\": {\n \"issuer\": \"https://login.acme.example\",\n \"client_id\": \"niadra-console\",\n \"client_secret\": \"the-client-secret-from-the-provider\",\n \"scopes\": [\n \"groups\"\n ]\n },\n \"reason\": \"The Console signs in with the company login\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://control.api.niadra.com/v1/sso")
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 \"protocol\": \"oidc\",\n \"domains\": [\n \"acme.example\"\n ],\n \"enabled\": true,\n \"enforced\": false,\n \"default_role\": null,\n \"role_mappings\": [\n {\n \"group\": \"niadra-admins\",\n \"role\": \"admin\"\n },\n {\n \"group\": \"cx-quality\",\n \"role\": \"review\"\n }\n ],\n \"groups_attribute\": \"groups\",\n \"require_second_factor\": false,\n \"oidc\": {\n \"issuer\": \"https://login.acme.example\",\n \"client_id\": \"niadra-console\",\n \"client_secret\": \"the-client-secret-from-the-provider\",\n \"scopes\": [\n \"groups\"\n ]\n },\n \"reason\": \"The Console signs in with the company login\"\n}"
response = http.request(request)
puts response.read_body{
"connection": {
"connection_id": "0192f8e5-93a4-75b6-8fc7-3c4d5e6f7a89",
"protocol": "oidc",
"domains": [
"acme.example"
],
"enabled": true,
"enforced": false,
"default_role": null,
"role_mappings": [
{
"group": "niadra-admins",
"role": "admin"
},
{
"group": "cx-quality",
"role": "review"
}
],
"groups_attribute": "groups",
"require_second_factor": false,
"oidc": {
"issuer": "https://login.acme.example",
"client_id": "niadra-console",
"scopes": [
"openid",
"email",
"profile",
"groups"
],
"client_secret_set": true
},
"saml": null,
"created_at": "2026-09-24T10:00:00Z",
"updated_at": "2026-09-24T10:00:00Z",
"updated_by": "0192f0a0-4e5f-7061-9c72-8d9e0f1a2b34"
},
"service_provider": {
"oidc_redirect_uri": "https://control.api.niadra.com/v1/auth/sso/oidc/callback",
"saml_entity_id": "urn:niadra:sso:0192f0a0-1b2c-7d3e-8f40-5a6b7c8d9e01",
"saml_acs_url": "https://control.api.niadra.com/v1/auth/sso/saml/0192f0a0-1b2c-7d3e-8f40-5a6b7c8d9e01/acs",
"saml_metadata_url": "https://control.api.niadra.com/v1/auth/sso/saml/0192f0a0-1b2c-7d3e-8f40-5a6b7c8d9e01/metadata"
}
}{
"code": "<string>",
"status": 123,
"title": "<string>",
"detail": "<string>",
"request_id": "<string>",
"type": "about:blank"
}Set up SSO
Creates or replaces the connection: domains, groups that give roles, default role and the sign-in rules.
curl --request PUT \
--url https://control.api.niadra.com/v1/sso \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"protocol": "oidc",
"domains": [
"acme.example"
],
"enabled": true,
"enforced": false,
"default_role": null,
"role_mappings": [
{
"group": "niadra-admins",
"role": "admin"
},
{
"group": "cx-quality",
"role": "review"
}
],
"groups_attribute": "groups",
"require_second_factor": false,
"oidc": {
"issuer": "https://login.acme.example",
"client_id": "niadra-console",
"client_secret": "the-client-secret-from-the-provider",
"scopes": [
"groups"
]
},
"reason": "The Console signs in with the company login"
}
'import requests
url = "https://control.api.niadra.com/v1/sso"
payload = {
"protocol": "oidc",
"domains": ["acme.example"],
"enabled": True,
"enforced": False,
"default_role": None,
"role_mappings": [
{
"group": "niadra-admins",
"role": "admin"
},
{
"group": "cx-quality",
"role": "review"
}
],
"groups_attribute": "groups",
"require_second_factor": False,
"oidc": {
"issuer": "https://login.acme.example",
"client_id": "niadra-console",
"client_secret": "the-client-secret-from-the-provider",
"scopes": ["groups"]
},
"reason": "The Console signs in with the company login"
}
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({
protocol: 'oidc',
domains: ['acme.example'],
enabled: true,
enforced: false,
default_role: null,
role_mappings: [{group: 'niadra-admins', role: 'admin'}, {group: 'cx-quality', role: 'review'}],
groups_attribute: 'groups',
require_second_factor: false,
oidc: {
issuer: 'https://login.acme.example',
client_id: 'niadra-console',
client_secret: 'the-client-secret-from-the-provider',
scopes: ['groups']
},
reason: 'The Console signs in with the company login'
})
};
fetch('https://control.api.niadra.com/v1/sso', 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://control.api.niadra.com/v1/sso",
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([
'protocol' => 'oidc',
'domains' => [
'acme.example'
],
'enabled' => true,
'enforced' => false,
'default_role' => null,
'role_mappings' => [
[
'group' => 'niadra-admins',
'role' => 'admin'
],
[
'group' => 'cx-quality',
'role' => 'review'
]
],
'groups_attribute' => 'groups',
'require_second_factor' => false,
'oidc' => [
'issuer' => 'https://login.acme.example',
'client_id' => 'niadra-console',
'client_secret' => 'the-client-secret-from-the-provider',
'scopes' => [
'groups'
]
],
'reason' => 'The Console signs in with the company login'
]),
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://control.api.niadra.com/v1/sso"
payload := strings.NewReader("{\n \"protocol\": \"oidc\",\n \"domains\": [\n \"acme.example\"\n ],\n \"enabled\": true,\n \"enforced\": false,\n \"default_role\": null,\n \"role_mappings\": [\n {\n \"group\": \"niadra-admins\",\n \"role\": \"admin\"\n },\n {\n \"group\": \"cx-quality\",\n \"role\": \"review\"\n }\n ],\n \"groups_attribute\": \"groups\",\n \"require_second_factor\": false,\n \"oidc\": {\n \"issuer\": \"https://login.acme.example\",\n \"client_id\": \"niadra-console\",\n \"client_secret\": \"the-client-secret-from-the-provider\",\n \"scopes\": [\n \"groups\"\n ]\n },\n \"reason\": \"The Console signs in with the company login\"\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://control.api.niadra.com/v1/sso")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"protocol\": \"oidc\",\n \"domains\": [\n \"acme.example\"\n ],\n \"enabled\": true,\n \"enforced\": false,\n \"default_role\": null,\n \"role_mappings\": [\n {\n \"group\": \"niadra-admins\",\n \"role\": \"admin\"\n },\n {\n \"group\": \"cx-quality\",\n \"role\": \"review\"\n }\n ],\n \"groups_attribute\": \"groups\",\n \"require_second_factor\": false,\n \"oidc\": {\n \"issuer\": \"https://login.acme.example\",\n \"client_id\": \"niadra-console\",\n \"client_secret\": \"the-client-secret-from-the-provider\",\n \"scopes\": [\n \"groups\"\n ]\n },\n \"reason\": \"The Console signs in with the company login\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://control.api.niadra.com/v1/sso")
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 \"protocol\": \"oidc\",\n \"domains\": [\n \"acme.example\"\n ],\n \"enabled\": true,\n \"enforced\": false,\n \"default_role\": null,\n \"role_mappings\": [\n {\n \"group\": \"niadra-admins\",\n \"role\": \"admin\"\n },\n {\n \"group\": \"cx-quality\",\n \"role\": \"review\"\n }\n ],\n \"groups_attribute\": \"groups\",\n \"require_second_factor\": false,\n \"oidc\": {\n \"issuer\": \"https://login.acme.example\",\n \"client_id\": \"niadra-console\",\n \"client_secret\": \"the-client-secret-from-the-provider\",\n \"scopes\": [\n \"groups\"\n ]\n },\n \"reason\": \"The Console signs in with the company login\"\n}"
response = http.request(request)
puts response.read_body{
"connection": {
"connection_id": "0192f8e5-93a4-75b6-8fc7-3c4d5e6f7a89",
"protocol": "oidc",
"domains": [
"acme.example"
],
"enabled": true,
"enforced": false,
"default_role": null,
"role_mappings": [
{
"group": "niadra-admins",
"role": "admin"
},
{
"group": "cx-quality",
"role": "review"
}
],
"groups_attribute": "groups",
"require_second_factor": false,
"oidc": {
"issuer": "https://login.acme.example",
"client_id": "niadra-console",
"scopes": [
"openid",
"email",
"profile",
"groups"
],
"client_secret_set": true
},
"saml": null,
"created_at": "2026-09-24T10:00:00Z",
"updated_at": "2026-09-24T10:00:00Z",
"updated_by": "0192f0a0-4e5f-7061-9c72-8d9e0f1a2b34"
},
"service_provider": {
"oidc_redirect_uri": "https://control.api.niadra.com/v1/auth/sso/oidc/callback",
"saml_entity_id": "urn:niadra:sso:0192f0a0-1b2c-7d3e-8f40-5a6b7c8d9e01",
"saml_acs_url": "https://control.api.niadra.com/v1/auth/sso/saml/0192f0a0-1b2c-7d3e-8f40-5a6b7c8d9e01/acs",
"saml_metadata_url": "https://control.api.niadra.com/v1/auth/sso/saml/0192f0a0-1b2c-7d3e-8f40-5a6b7c8d9e01/metadata"
}
}{
"code": "<string>",
"status": 123,
"title": "<string>",
"detail": "<string>",
"request_id": "<string>",
"type": "about:blank"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
The e-mail domains whose people sign in through this connection. Each domain belongs to one tenant; public mailboxes (gmail.com and the like) are refused.
1 - 20 elementsoidc, saml Why, kept in the tenant's access history.
3 - 1000For a person in no mapped group; null lets in only people of mapped groups.
admin, security, integration, review, analysis, vendor People of the domains sign in only through SSO. A tenant-wide admin keeps the password, as the way in when the provider fails.
The claim (OIDC) or attribute (SAML) that carries the groups.
1 - 256Show child attributes
Show child attributes
Ask for the Niadra authenticator code after the provider, on top of the provider's MFA.
100Show child attributes
Show child attributes
Show child attributes
Show child attributes
Response
The connection as stored, and what to paste into the identity provider.

