SSO connections API
SSO connections endpoints in the Brix REST API: 11 operations (GET, POST, PATCH, DELETE). Each lists its path, auth, required permission and a curl example.
View as Markdown · For AI agents: the full docs index is at /llms.txt
Base URL https://api.brixsignage.com. Send Authorization: Bearer $BRIX_API_KEY unless an operation says Auth: none or Auth: no API key. The Permission line names what the key must hold. See Authentication and scopes, Errors and rate limits and Pagination.
GET /v1/sso-connectionsPOST /v1/sso-connectionsPATCH /v1/sso-connections/{id}DELETE /v1/sso-connections/{id}GET /v1/sso-connections/{id}/domain-challengeGET /v1/sso-connections/{id}/scimPOST /v1/sso-connections/{id}/scim/tokensDELETE /v1/sso-connections/{id}/scim/tokens/{tokenId}POST /v1/sso-connections/{id}/test-mappingPOST /v1/sso-connections/{id}/verify-domainsPOST /v1/sso-connections/test
Every 4xx and 5xx response below returns this body:
| Field | Type | Description |
|---|---|---|
error | string | Machine-readable code: unauthorized, forbidden, not_found, validation_error, conflict, rate_limited, internal_error, … |
message | string | Human-readable explanation. Safe to show an operator. |
requestId | string | Present on 5xx: quote it to support. |
GET /v1/sso-connections
Returns the workspace's enterprise single sign-on connections, with client secrets masked. The key or person must have settings.view for the whole workspace. A caller limited to a location or to a franchise workspace gets 403. lastClaims holds the claims from the last sign-in: a person's email, name and groups. It is null unless the caller also has user.view for the whole workspace.
curl "https://api.brixsignage.com/v1/sso-connections" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | array of SsoConnection | |
data[].id | string | |
data[].displayName | string | |
data[].vendor | string | Free text; generic-oidc when not set. |
data[].issuer | string | The OpenID Connect issuer URL (https://, no trailing slash). |
data[].clientId | string | |
data[].clientSecretPreview | "••••••••" | Always this mask: the client secret is stored encrypted and is never returned. |
data[].emailDomains | string | Comma-separated, lower-case (a leading @ and a trailing dot are removed). |
data[].domainsVerifiedAt | string | null | When DNS proved the domains; null until verified. An unverified connection is not offered at sign-in. |
data[].provenAt | string | null | When a sign-in first completed with the current issuer, client and domains; null until then. |
data[].lastSignInAt | string | null | The latest sign-in through this connection. Only the list fills it; create and update answer null. |
data[].jitProvisioning | boolean | Create a person on their first sign-in. |
data[].defaultRoleId | string | null | The role a new person gets at the workspace root when no rule applies. |
data[].claimMapping | SsoClaimMapping | null | |
data[].extraScopes | string | null | Scopes requested on top of openid email profile, space-separated. |
data[].lastClaims | object | null | The claims of the last sign-in (a person's email, name and groups). Null unless the caller also holds user.view for the whole workspace. |
data[].lastClaimsAt | string | null | |
data[].enabled | boolean | |
data[].redirectUri | string | The redirect URI to register in the identity provider. |
data[].createdAt | string | ISO-8601 timestamp (UTC). |
data[].updatedAt | string | ISO-8601 timestamp (UTC). |
Response 401: Missing, expired or revoked bearer token.
Response 403: You do not hold the permission for the whole workspace (a grant at one location, or in a franchise workspace, is not enough).
Response 5XX: Server error. The body carries a requestId to quote to support.
POST /v1/sso-connections
Creates an enterprise single sign-on connection. The client secret is encrypted before it is stored.
Notes.
- A new connection is unverified: prove its domains (domain-challenge, then verify-domains) before it is offered at sign-in.
Request body: application/json
| Field | Type | Required | Description |
|---|---|---|---|
displayName | string | yes | |
vendor | string | no | Free text, e.g. okta, entra. |
issuer | string | yes | Must start with https://. A trailing slash is removed. |
clientId | string | yes | |
clientSecret | string | yes | Encrypted before it is stored; never returned. |
emailDomains | string | yes | Comma-separated email domains, e.g. acme.com,acme.org. |
jitProvisioning | boolean | no | Default true. |
enabled | boolean | no | Default true. |
defaultRoleId | string | null | no | You must be able to grant this role for the whole workspace. |
claimMapping | SsoClaimMapping | null | no | You must be able to grant each rule's role where the rule grants it. Null clears it. |
extraScopes | string | null | no | Space- or comma-separated scope tokens (at most 20). Null or empty clears them. |
curl -X POST "https://api.brixsignage.com/v1/sso-connections" \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"displayName":"Acme Okta","issuer":"https://acme.okta.com","clientId":"0oa1b2c3d4","clientSecret":"example-client-secret","emailDomains":"acme.com"}' Response 201: Success.
| Field | Type | Description |
|---|---|---|
data | SsoConnection | An enterprise single sign-on (OpenID Connect) connection. |
data.id | string | |
data.displayName | string | |
data.vendor | string | Free text; generic-oidc when not set. |
data.issuer | string | The OpenID Connect issuer URL (https://, no trailing slash). |
data.clientId | string | |
data.clientSecretPreview | "••••••••" | Always this mask: the client secret is stored encrypted and is never returned. |
data.emailDomains | string | Comma-separated, lower-case (a leading @ and a trailing dot are removed). |
data.domainsVerifiedAt | string | null | When DNS proved the domains; null until verified. An unverified connection is not offered at sign-in. |
data.provenAt | string | null | When a sign-in first completed with the current issuer, client and domains; null until then. |
data.lastSignInAt | string | null | The latest sign-in through this connection. Only the list fills it; create and update answer null. |
data.jitProvisioning | boolean | Create a person on their first sign-in. |
data.defaultRoleId | string | null | The role a new person gets at the workspace root when no rule applies. |
data.claimMapping | SsoClaimMapping | null | |
data.extraScopes | string | null | Scopes requested on top of openid email profile, space-separated. |
data.lastClaims | object | null | The claims of the last sign-in (a person's email, name and groups). Null unless the caller also holds user.view for the whole workspace. |
data.lastClaimsAt | string | null | |
data.enabled | boolean | |
data.redirectUri | string | The redirect URI to register in the identity provider. |
data.createdAt | string | ISO-8601 timestamp (UTC). |
data.updatedAt | string | ISO-8601 timestamp (UTC). |
Response 401: Missing, expired or revoked bearer token.
Response 403: You do not hold the permission for the whole workspace (a grant at one location, or in a franchise workspace, is not enough). Also: defaultRoleId or a rule's role holds permissions you cannot grant there.
Response 404: No such connection, role or location in this workspace.
Response 422: A required field is missing, issuer is not https://, an invalid claimMapping, or extraScopes is not a valid scope list.
Response 5XX: Server error. The body carries a requestId to quote to support.
PATCH /v1/sso-connections/{id}
Updates an enterprise single sign-on connection. clientSecret is optional: when provided, it replaces the stored secret; when omitted, the existing secret is left unchanged.
Notes.
- Changing emailDomains, issuer or clientId clears domainsVerifiedAt (the DNS proof vouches for the IdP too; publish the new challenge and verify again). Changing issuer, clientId, clientSecret or emailDomains clears provenAt.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | SSO connection id. |
Request body: application/json
| Field | Type | Required | Description |
|---|---|---|---|
displayName | string | no | |
vendor | string | no | Free text, e.g. okta, entra. |
issuer | string | no | Must start with https://. A trailing slash is removed. |
clientId | string | no | |
clientSecret | string | no | Replaces the stored secret. Omitted or empty keeps it. |
emailDomains | string | no | Comma-separated email domains, e.g. acme.com,acme.org. |
jitProvisioning | boolean | no | Default true. |
enabled | boolean | no | Default true. |
defaultRoleId | string | null | no | You must be able to grant this role for the whole workspace. |
claimMapping | SsoClaimMapping | null | no | You must be able to grant each rule's role where the rule grants it. Null clears it. |
extraScopes | string | null | no | Space- or comma-separated scope tokens (at most 20). Null or empty clears them. |
curl -X PATCH "https://api.brixsignage.com/v1/sso-connections/{id}" \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | SsoConnection | An enterprise single sign-on (OpenID Connect) connection. |
data.id | string | |
data.displayName | string | |
data.vendor | string | Free text; generic-oidc when not set. |
data.issuer | string | The OpenID Connect issuer URL (https://, no trailing slash). |
data.clientId | string | |
data.clientSecretPreview | "••••••••" | Always this mask: the client secret is stored encrypted and is never returned. |
data.emailDomains | string | Comma-separated, lower-case (a leading @ and a trailing dot are removed). |
data.domainsVerifiedAt | string | null | When DNS proved the domains; null until verified. An unverified connection is not offered at sign-in. |
data.provenAt | string | null | When a sign-in first completed with the current issuer, client and domains; null until then. |
data.lastSignInAt | string | null | The latest sign-in through this connection. Only the list fills it; create and update answer null. |
data.jitProvisioning | boolean | Create a person on their first sign-in. |
data.defaultRoleId | string | null | The role a new person gets at the workspace root when no rule applies. |
data.claimMapping | SsoClaimMapping | null | |
data.extraScopes | string | null | Scopes requested on top of openid email profile, space-separated. |
data.lastClaims | object | null | The claims of the last sign-in (a person's email, name and groups). Null unless the caller also holds user.view for the whole workspace. |
data.lastClaimsAt | string | null | |
data.enabled | boolean | |
data.redirectUri | string | The redirect URI to register in the identity provider. |
data.createdAt | string | ISO-8601 timestamp (UTC). |
data.updatedAt | string | ISO-8601 timestamp (UTC). |
Response 401: Missing, expired or revoked bearer token.
Response 403: You do not hold the permission for the whole workspace (a grant at one location, or in a franchise workspace, is not enough). Also: defaultRoleId or a rule's role holds permissions you cannot grant there. Changing claimMapping or defaultRoleId (clearing included) also needs you to be able to grant every role the CURRENT mapping and default role give; a mapping that seats Owners can be changed only by an Owner signed in as a person. Changing issuer, clientId or emailDomains, or setting enabled back to true, needs an Owner signed in as a person (owner_required).
Response 404: No such connection, role or location in this workspace.
Response 422: A required field is missing, issuer is not https://, an invalid claimMapping, or extraScopes is not a valid scope list.
Response 5XX: Server error. The body carries a requestId to quote to support.
DELETE /v1/sso-connections/{id}
Soft-deletes an enterprise single sign-on connection.
Notes.
- Answers { ok: true }, not the { id, deleted } shape of other deletes. The connection is also disabled.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | SSO connection id. |
curl -X DELETE "https://api.brixsignage.com/v1/sso-connections/{id}" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.ok | true |
Response 401: Missing, expired or revoked bearer token.
Response 403: You do not hold the permission for the whole workspace (a grant at one location, or in a franchise workspace, is not enough).
Response 404: No such connection in this workspace.
Response 5XX: Server error. The body carries a requestId to quote to support.
GET /v1/sso-connections/{id}/domain-challenge
Returns the DNS TXT records you must publish to prove control of the email domains used by this SSO connection. The key or person must have settings.view for the whole workspace.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | SSO connection id. |
curl "https://api.brixsignage.com/v1/sso-connections/{id}/domain-challenge" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.records | array of object | |
data.records[].domain | string | |
data.records[].name | string | The record name: _brix-verify.<domain>. |
data.records[].type | "TXT" | |
data.records[].value | string | The record value to publish: brix-domain-verify=<token>. |
data.verifiedAt | string | null |
Response 401: Missing, expired or revoked bearer token.
Response 403: You do not hold the permission for the whole workspace (a grant at one location, or in a franchise workspace, is not enough).
Response 404: No such connection in this workspace.
Response 5XX: Server error. The body carries a requestId to quote to support.
GET /v1/sso-connections/{id}/scim
Returns the SCIM base URL for this SSO connection and a preview of its currently live provisioning tokens. Token secrets themselves are never returned.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | SSO connection id. |
curl "https://api.brixsignage.com/v1/sso-connections/{id}/scim" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.baseUrl | string | The SCIM 2.0 base URL to give the identity provider. |
data.tokens | array of object | Live tokens only. |
data.tokens[].id | string | |
data.tokens[].preview | string | •••• and the last four characters. |
data.tokens[].createdAt | string | ISO-8601 timestamp (UTC). |
data.tokens[].lastUsedAt | string | null |
Response 401: Missing, expired or revoked bearer token.
Response 403: You do not hold the permission for the whole workspace (a grant at one location, or in a franchise workspace, is not enough).
Response 404: No such connection in this workspace.
Response 5XX: Server error. The body carries a requestId to quote to support.
POST /v1/sso-connections/{id}/scim/tokens
Creates a new SCIM provisioning token for this SSO connection. The token value is shown exactly once, in this response. A connection can have at most 5 live tokens at a time. Only a workspace Owner, signed in as a person, can create one; the token stops working if that person is no longer an Owner. This action cannot be taken while impersonating another user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | SSO connection id. |
curl -X POST "https://api.brixsignage.com/v1/sso-connections/{id}/scim/tokens" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 201: Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.id | string | |
data.token | string | The SCIM bearer token. Shown only here; store it now. |
data.baseUrl | string |
Response 401: Missing, expired or revoked bearer token.
Response 403: You do not hold the permission for the whole workspace (a grant at one location, or in a franchise workspace, is not enough). owner_required: only a workspace Owner, signed in as a person, can create a SCIM token (not an API key). The token stops working if that person is no longer an Owner.
Response 404: No such connection in this workspace.
Response 409: too_many_tokens: the connection already has 5 live tokens.
Response 5XX: Server error. The body carries a requestId to quote to support.
DELETE /v1/sso-connections/{id}/scim/tokens/{tokenId}
Revokes one SCIM provisioning token belonging to this SSO connection.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | SSO connection id. |
tokenId | path | string | yes | SCIM token id. |
curl -X DELETE "https://api.brixsignage.com/v1/sso-connections/{id}/scim/tokens/{tokenId}" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.ok | true |
Response 401: Missing, expired or revoked bearer token.
Response 403: You do not hold the permission for the whole workspace (a grant at one location, or in a franchise workspace, is not enough).
Response 404: No such connection, or no live token with this id.
Response 5XX: Server error. The body carries a requestId to quote to support.
POST /v1/sso-connections/{id}/test-mapping
Previews the role and location a person would be granted, given a set of example identity-provider claims, by running the same mapping logic used at sign-in. This is read-only and does not sign anyone in or change anything.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | SSO connection id. |
Request body: application/json
| Field | Type | Required | Description |
|---|---|---|---|
claims | object | yes | Example identity-provider claims. |
claimMapping | SsoClaimMapping | null | no | An unsaved mapping to test; omitted = the saved one. |
curl -X POST "https://api.brixsignage.com/v1/sso-connections/{id}/test-mapping" \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.mapped | boolean | False when there is no mapping: grants is then the default role at the root, without names. |
data.grants | array of object | |
data.grants[].nodeId | string | Location id (the workspace id for the root). |
data.grants[].roleId | string | |
data.grants[].roleName | string | null | Absent when mapped is false. |
data.grants[].nodeName | string | null | Absent when mapped is false. |
data.matchedRules | array of integer | Indexes of the rules that matched. |
data.unmatchedLocations | array of string | Location values that matched no location. |
data.ambiguousLocations | array of string | Location values that matched more than one location. |
data.usedDefault | boolean | |
data.denied | boolean | True when the sign-in would be refused (noMatch: deny). |
Response 401: Missing, expired or revoked bearer token.
Response 403: You do not hold the permission for the whole workspace (a grant at one location, or in a franchise workspace, is not enough).
Response 404: No such connection in this workspace.
Response 422: claims is not an object, or claimMapping is invalid.
Response 5XX: Server error. The body carries a requestId to quote to support.
POST /v1/sso-connections/{id}/verify-domains
Verifies an SSO connection's email domains using a DNS TXT record lookup. Verified domains control whether the connection is offered at sign-in and whether cross-workspace sign-in is allowed for that domain.
Notes.
- Answers 200 with verified: false when a domain fails; the connection stays unverified.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | SSO connection id. |
curl -X POST "https://api.brixsignage.com/v1/sso-connections/{id}/verify-domains" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.verified | boolean | True only when every domain proved out. |
data.results | array of object | |
data.results[].domain | string | |
data.results[].ok | boolean | |
data.results[].reason | string | Why a domain failed: claimed_by_another_workspace, dns_<status>, or a lookup error. Absent when the lookup answered. |
data.verifiedAt | string | null |
Response 401: Missing, expired or revoked bearer token.
Response 403: You do not hold the permission for the whole workspace (a grant at one location, or in a franchise workspace, is not enough).
Response 404: No such connection in this workspace.
Response 422: no_domains: the connection has no email domains.
Response 5XX: Server error. The body carries a requestId to quote to support.
POST /v1/sso-connections/test
Fetches the identity provider's OpenID Connect discovery document and returns its parsed authorization, token, and key endpoints, so the connection can be confirmed as reachable before the setup form is submitted.
Notes.
- Needs settings.view held anywhere, unlike the other SSO routes, which need it for the whole workspace.
Request body: application/json
| Field | Type | Required | Description |
|---|---|---|---|
issuer | string | yes | Must start with https://. |
curl -X POST "https://api.brixsignage.com/v1/sso-connections/test" \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.ok | true | |
data.issuer | string | The issuer the discovery document names; absent when it names none. |
data.authorizationEndpoint | string | |
data.tokenEndpoint | string | |
data.jwksUri | string |
Response 401: Missing, expired or revoked bearer token.
Response 403: The token lacks the permission this operation needs (see x-brix-permission).
Response 422: issuer is not https://.
Response 502: discovery_failed (the provider answered an error), discovery_incomplete (an endpoint is missing), or discovery_threw (not reachable).
Response 5XX: Server error. The body carries a requestId to quote to support.