SSO API

Manage single sign-on configuration programmatically. Configure SAML 2.0 and OpenID Connect providers, verify domains, control enforcement, and inspect SSO sessions through the REST API.

Role requirements

All SSO configuration endpoints require the Admin role. Public authentication flow endpoints do not require authentication and are used during the SSO login process.

Authentication

Admin endpoints require a session cookie or API token with Admin role. Pass the token via the Authorization: Bearer <token> header.

Get SSO Configuration

GET
/api/sso/team/{teamId}/config

Retrieve the current SSO configuration for a team.

Path Parameters

ParameterTypeRequiredDescription
teamIdUUIDYesThe team ID to retrieve SSO configuration for.

Response

200 OK
{
  "protocol": "SAML",
  "enabled": true,
  "enforced": false,
  "domainVerified": true,
  "verifiedDomains": ["example.com"],
  "saml": {
    "entityId": "https://idp.example.com/saml/metadata",
    "ssoUrl": "https://idp.example.com/saml/sso",
    "certificateFingerprint": "AB:CD:EF:12:34:56:78:90",
    "signRequests": true,
    "forceAuthn": false
  },
  "oidc": null,
  "autoProvisionEnabled": true,
  "defaultRole": "VIEWER",
  "sessionDurationHours": 8,
  "createdAt": "2026-01-15T10:00:00Z",
  "updatedAt": "2026-03-20T14:30:00Z"
}

Configure SAML 2.0

POST
/api/sso/team/{teamId}/saml

Create or update the SAML 2.0 SSO configuration for a team.

Request Body

FieldTypeRequiredDescription
entityIdstringYesThe IdP entity ID (Issuer URL) from your identity provider.
ssoUrlstringYesThe IdP single sign-on URL where SAML authentication requests are sent.
certificatestringYesThe IdP X.509 signing certificate in PEM format.
signRequestsbooleanNoWhether to sign SAML authentication requests. Default: true.
forceAuthnbooleanNoWhether to force re-authentication at the IdP. Default: false.
attributeMappingobjectNoCustom attribute name overrides for email, firstName, and lastName.
Request example
{
  "entityId": "https://idp.example.com/saml/metadata",
  "ssoUrl": "https://idp.example.com/saml/sso",
  "certificate": "-----BEGIN CERTIFICATE-----\nMIIC...base64...\n-----END CERTIFICATE-----",
  "signRequests": true,
  "forceAuthn": false,
  "attributeMapping": {
    "email": "urn:oid:0.9.2342.19200300.100.1.3",
    "firstName": "urn:oid:2.5.4.42",
    "lastName": "urn:oid:2.5.4.4"
  }
}
201 Created
{
  "protocol": "SAML",
  "entityId": "https://idp.example.com/saml/metadata",
  "ssoUrl": "https://idp.example.com/saml/sso",
  "certificateFingerprint": "AB:CD:EF:12:34:56:78:90",
  "signRequests": true,
  "forceAuthn": false,
  "createdAt": "2026-03-30T12:00:00Z"
}

Configure OpenID Connect

POST
/api/sso/team/{teamId}/oidc

Create or update the OpenID Connect SSO configuration for a team.

Request Body

FieldTypeRequiredDescription
issuerUrlstringYesThe OIDC issuer URL. NodeLoom fetches the discovery document from {issuerUrl}/.well-known/openid-configuration.
clientIdstringYesThe OAuth 2.0 client ID from your identity provider.
clientSecretstringYesThe OAuth 2.0 client secret. Stored encrypted at rest.
scopesstring[]NoOIDC scopes to request. Default: ["openid", "profile", "email"].
attributeMappingobjectNoCustom claim name overrides for email, firstName, and lastName.
Request example
{
  "issuerUrl": "https://idp.example.com",
  "clientId": "0oa1b2c3d4e5f6g7h8i9",
  "clientSecret": "your-client-secret",
  "scopes": ["openid", "profile", "email"],
  "attributeMapping": {
    "email": "email",
    "firstName": "given_name",
    "lastName": "family_name"
  }
}
201 Created
{
  "protocol": "OIDC",
  "issuerUrl": "https://idp.example.com",
  "clientId": "0oa1b2c3d4e5f6g7h8i9",
  "scopes": ["openid", "profile", "email"],
  "createdAt": "2026-03-30T12:00:00Z"
}

Enable SSO

POST
/api/sso/team/{teamId}/enable

Enable SSO for the team. A valid SAML or OIDC configuration must exist.

Request example
{
  "enabled": true
}
200 OK
{
  "enabled": true,
  "protocol": "SAML",
  "message": "SSO has been enabled. Users can now authenticate via your identity provider."
}

Test before enabling

Before enabling SSO, test the configuration by navigating to the SSO login URL in an incognito window. Enabling SSO with an incorrect configuration may prevent users from logging in.

Enforce SSO

POST
/api/sso/team/{teamId}/enforce

Enforce SSO for all team members with a verified domain. Blocks password and social login.

Prerequisites

RequirementDescription
SSO enabledSSO must be enabled before enforcement can be activated.
Domain verifiedAt least one email domain must be verified.
Request example
{
  "enforced": true
}
200 OK
{
  "enforced": true,
  "verifiedDomains": ["example.com"],
  "message": "SSO enforcement is active. All users with @example.com email addresses must authenticate via SSO."
}

Lockout risk

Enforcing SSO blocks all non-SSO authentication for matching domain users. Only the team owner retains password login access as a safety bypass. Ensure your IdP is correctly configured and accessible before enabling enforcement.

SAML Login (Public)

GET
/api/sso/saml/{teamId}/login

Initiate the SAML authentication flow. Redirects the user to the IdP login page.

This endpoint does not require authentication. It generates a SAML AuthnRequest and redirects the browser to the identity provider's SSO URL. After authentication, the IdP posts the SAML response to the ACS endpoint.

Query Parameters

ParameterTypeRequiredDescription
returnTostringNoURL to redirect to after successful authentication. Must be a relative path.

SAML ACS (Public)

POST
/api/sso/saml/{teamId}/acs

Assertion Consumer Service. Receives the SAML response from the IdP and creates a session.

This endpoint receives the SAML response posted by the identity provider after successful authentication. NodeLoom validates the assertion signature, extracts user attributes, provisions or links the user account, and creates a session.

Form Parameters

ParameterTypeDescription
SAMLResponsestringBase64-encoded SAML response from the identity provider.
RelayStatestringOptional relay state containing the return URL.

OIDC Authorize (Public)

GET
/api/sso/oidc/{teamId}/authorize

Initiate the OIDC authorization code flow. Redirects to the IdP authorization endpoint.

This endpoint does not require authentication. It generates a state parameter, PKCE code verifier, and redirects the browser to the identity provider's authorization endpoint.

Query Parameters

ParameterTypeRequiredDescription
returnTostringNoURL to redirect to after successful authentication. Must be a relative path.

OIDC Callback (Public)

GET
/api/sso/oidc/{teamId}/callback

OIDC callback. Exchanges the authorization code for tokens and creates a session.

This endpoint is called by the identity provider after the user authorizes the application. NodeLoom exchanges the authorization code for an access token and ID token, extracts user claims, provisions or links the account, and creates a session.

Query Parameters

ParameterTypeRequiredDescription
codestringYesThe authorization code from the identity provider.
statestringYesThe state parameter for CSRF protection. Must match the value generated during authorization.

SSO Check (Public)

GET
/api/sso/check?email=

Check if an email address is associated with an SSO-enabled team.

This endpoint is used by the login form to determine whether an email address should be redirected to an SSO login flow. It is rate-limited to prevent email enumeration.

Query Parameters

ParameterTypeRequiredDescription
emailstringYesThe email address to check for SSO association.
200 OK (SSO enabled)
{
  "ssoEnabled": true,
  "protocol": "SAML",
  "loginUrl": "/api/sso/saml/team_xyz789/login"
}
200 OK (SSO not enabled)
{
  "ssoEnabled": false
}

Error Responses

All SSO API endpoints return standard error responses with the following structure:

Error response format
{
  "error": "sso_configuration_invalid",
  "message": "The SAML certificate has expired.",
  "status": 400
}
StatusError CodeDescription
400sso_configuration_invalidThe SSO configuration is missing required fields or contains invalid values.
401unauthorizedThe request is not authenticated or the session has expired.
403forbiddenThe authenticated user does not have Admin role.
404team_not_foundThe specified team ID does not exist.
409sso_already_enabledSSO is already enabled. Disable it first to change the protocol.
422domain_not_verifiedCannot enforce SSO without at least one verified domain.
429rate_limitedToo many requests. Check the Retry-After header.