Opti ID Integration Specification
Why enterprise identity integration matters
Section titled “Why enterprise identity integration matters”Organizations adopting Optimizely need their existing identity infrastructure to work seamlessly with the platform. Without proper integration, administrators face manual user provisioning, employees manage yet another password, and security teams lose visibility into access patterns. Opti ID bridges this gap by supporting industry-standard identity protocols.
This reference covers the technical details of connecting Opti ID to your identity provider (IdP) using SAML 2.0 or OpenID Connect, automating user lifecycle management through SCIM, and configuring session and MFA policies.
SAML 2.0 configuration
Section titled “SAML 2.0 configuration”Opti ID acts as a SAML 2.0 Service Provider (SP). Your enterprise identity provider (IdP) — such as Entra ID, Okta, or Ping Identity — authenticates users and sends SAML assertions to Opti ID.
Service Provider metadata
Section titled “Service Provider metadata”| Field | Value |
|---|---|
| Entity ID | https://id.optimizely.com/saml/metadata/{org-id} |
| ACS URL | https://id.optimizely.com/saml/acs/{org-id} |
| SLO URL | https://id.optimizely.com/saml/slo/{org-id} |
| Metadata URL | https://id.optimizely.com/saml/metadata/{org-id} |
| NameID format | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress |
| Binding | HTTP-POST (ACS), HTTP-Redirect (SLO) |
Replace {org-id} with your Optimizely organization identifier, found in Opti ID Admin > Organization Settings.
Required SAML attributes
Section titled “Required SAML attributes”Your IdP must send these attributes in the SAML assertion:
| Attribute | SAML claim | Required | Description |
|---|---|---|---|
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress | Yes | Primary user identifier | |
| First name | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname | Yes | User’s given name |
| Last name | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname | Yes | User’s family name |
| Groups | http://schemas.xmlsoap.org/claims/Group | No | Group memberships for role mapping |
| Department | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/department | No | Used for organization-level role mapping |
IdP configuration requirements
Section titled “IdP configuration requirements”<!-- Example IdP metadata requirements --><md:EntityDescriptor entityID="https://your-idp.example.com"> <md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> <md:KeyDescriptor use="signing"> <!-- Your IdP signing certificate --> </md:KeyDescriptor> <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://your-idp.example.com/sso/saml" /> </md:IDPSSODescriptor></md:EntityDescriptor>Signing and encryption
Section titled “Signing and encryption”| Setting | Value |
|---|---|
| AuthnRequest signing | Required (RSA-SHA256) |
| Assertion signature validation | Required |
| Assertion encryption | Optional (AES-256-CBC) |
| Certificate format | X.509, PEM-encoded |
| Minimum key length | 2048-bit RSA |
Setup steps
Section titled “Setup steps”- Download SP metadata from
https://id.optimizely.com/saml/metadata/{org-id} - Import SP metadata into your IdP
- Configure attribute mappings in your IdP
- Export IdP metadata XML
- Upload IdP metadata in Opti ID Admin > SSO > SAML Configuration
- Test with a non-admin user before enabling for the organization
- Enable SAML for the organization
OpenID Connect (OIDC) configuration
Section titled “OpenID Connect (OIDC) configuration”Opti ID supports OIDC as an alternative to SAML. OIDC is typically simpler to configure and better suited for modern identity providers.
Client registration
Section titled “Client registration”Register Opti ID as an OIDC Relying Party (RP) in your IdP:
| Field | Value |
|---|---|
| Client type | Confidential |
| Redirect URI | https://id.optimizely.com/oidc/callback/{org-id} |
| Post-logout redirect URI | https://id.optimizely.com/oidc/logout-callback/{org-id} |
| Response type | code |
| Grant type | Authorization Code with PKCE |
| Token endpoint auth | client_secret_post or private_key_jwt |
Required scopes
Section titled “Required scopes”| Scope | Purpose |
|---|---|
openid | Required for OIDC |
profile | First name, last name |
email | Email address |
groups | Group memberships (optional, for role mapping) |
Discovery endpoint
Section titled “Discovery endpoint”If your IdP supports OIDC Discovery, provide the well-known URL:
https://your-idp.example.com/.well-known/openid-configurationOpti ID reads issuer, authorization, token, userinfo, and JWKS endpoints automatically from the discovery document.
Manual endpoint configuration
Section titled “Manual endpoint configuration”If discovery is unavailable, configure endpoints individually in Opti ID Admin > SSO > OIDC Configuration:
| Endpoint | Description |
|---|---|
| Authorization | Where Opti ID redirects users to authenticate |
| Token | Where Opti ID exchanges the authorization code |
| UserInfo | Where Opti ID fetches user profile attributes |
| JWKS URI | Where Opti ID retrieves public keys for token validation |
| End session | Where Opti ID redirects for logout (optional) |
ID token claims mapping
Section titled “ID token claims mapping”| Opti ID field | Standard claim | Fallback claim |
|---|---|---|
email | preferred_username | |
| First name | given_name | name (split) |
| Last name | family_name | name (split) |
| Groups | groups | roles |
How the portal resolves the display name
Section titled “How the portal resolves the display name”The id_token alone often omits name claims (Okta returns them from the userinfo
endpoint, not the token). After exchanging the authorization code, the portal calls
the userinfo endpoint with the access token and merges those attributes over the
id_token claims, then resolves the display name in this order:
namegiven_name+family_name(composed)preferred_username- the email local-part (last-resort fallback)
The userinfo fetch is non-blocking — if it fails, login still succeeds using the id_token claims. Accounts previously stored with the email local-part are repaired automatically on their next sign-in.
Company capture from Opti ID is under evaluation: company is not a standard OIDC claim, so the exact source attribute is being confirmed from live userinfo payloads before it is auto-populated. Admins can set a user’s company manually in Certification Admin > Users in the meantime.
SCIM provisioning
Section titled “SCIM provisioning”SCIM 2.0 automates user lifecycle management — creating accounts when employees join, updating attributes when roles change, and deactivating accounts when employees leave.
SCIM endpoint
Section titled “SCIM endpoint”https://id.optimizely.com/scim/v2/{org-id}Authentication
Section titled “Authentication”SCIM requests require a bearer token:
Authorization: Bearer {scim-token}Generate SCIM tokens in Opti ID Admin > Provisioning > SCIM Configuration.
Supported resources
Section titled “Supported resources”Users (/scim/v2/{org-id}/Users)
Section titled “Users (/scim/v2/{org-id}/Users)”Create user:
POST /scim/v2/{org-id}/UsersContent-Type: application/scim+json
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "userName": "jane.doe@example.com", "name": { "givenName": "Jane", "familyName": "Doe" }, "emails": [ { "primary": true, "value": "jane.doe@example.com", "type": "work" } ], "active": true}Update user (PATCH):
PATCH /scim/v2/{org-id}/Users/{user-id}Content-Type: application/scim+json
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "name.familyName", "value": "Smith" } ]}Deactivate user:
PATCH /scim/v2/{org-id}/Users/{user-id}Content-Type: application/scim+json
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "active", "value": false } ]}List users with filter:
GET /scim/v2/{org-id}/Users?filter=userName eq "jane.doe@example.com"Groups (/scim/v2/{org-id}/Groups)
Section titled “Groups (/scim/v2/{org-id}/Groups)”Create group:
POST /scim/v2/{org-id}/GroupsContent-Type: application/scim+json
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"], "displayName": "CMS Editors", "members": [ { "value": "{user-id}", "display": "Jane Doe" } ]}Add member to group:
PATCH /scim/v2/{org-id}/Groups/{group-id}Content-Type: application/scim+json
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "add", "path": "members", "value": [{ "value": "{user-id}" }] } ]}SCIM-to-Optimizely role mapping
Section titled “SCIM-to-Optimizely role mapping”Map IdP groups to Optimizely roles in Opti ID Admin > Provisioning > Role Mapping:
| IdP group | Optimizely role | Products |
|---|---|---|
OptimizelyAdmins | Organization Admin | All |
CMSEditors | CMS Editor | CMS |
CMSAdmins | CMS Admin | CMS |
ExperimentationUsers | Experimenter | Experimentation |
AnalyticsViewers | Viewer | Analytics |
Supported SCIM operations
Section titled “Supported SCIM operations”| Operation | Users | Groups |
|---|---|---|
GET (list) | Yes | Yes |
GET (single) | Yes | Yes |
POST (create) | Yes | Yes |
PUT (replace) | Yes | Yes |
PATCH (update) | Yes | Yes |
DELETE | Deactivate only | Yes |
Session management
Section titled “Session management”Token formats
Section titled “Token formats”Opti ID issues two token types after authentication:
Access token (JWT):
| Claim | Description |
|---|---|
sub | User ID |
email | User email |
org_id | Organization ID |
roles | Array of role assignments |
products | Array of product entitlements |
exp | Expiration timestamp |
iss | https://id.optimizely.com |
aud | Target product identifier |
Refresh token (opaque):
- Used to obtain new access tokens without re-authentication
- Stored server-side, referenced by opaque handle
- Bound to the originating device and IP range (configurable)
Session lifetimes
Section titled “Session lifetimes”| Setting | Default | Configurable range |
|---|---|---|
| Access token TTL | 15 minutes | 5–60 minutes |
| Refresh token TTL | 8 hours | 1–24 hours |
| Absolute session timeout | 12 hours | 4–24 hours |
| Idle session timeout | 30 minutes | 15–120 minutes |
| Remember me duration | 30 days | 7–90 days |
Configure session lifetimes in Opti ID Admin > Security > Session Policy.
Token refresh flow
Section titled “Token refresh flow”1. Client detects access token expiration2. Client sends refresh token to POST /oauth/token3. Opti ID validates refresh token4. Opti ID issues new access token + rotated refresh token5. Old refresh token is invalidated (rotation)Session revocation
Section titled “Session revocation”POST /api/v1/sessions/revokeAuthorization: Bearer {admin-access-token}Content-Type: application/json
{ "user_id": "{user-id}", "scope": "all" // "all" | "current" | "other"}MFA configuration
Section titled “MFA configuration”Multi-factor authentication adds a second verification step after password authentication.
Supported MFA methods
Section titled “Supported MFA methods”| Method | Description | Recommended for |
|---|---|---|
| TOTP | Time-based one-time password (authenticator app) | All users |
| WebAuthn/FIDO2 | Hardware security keys, biometrics | High-security environments |
| SMS | Text message codes | Fallback only (less secure) |
| Email verification codes | Low-risk environments |
Organization MFA policy
Section titled “Organization MFA policy”Configure in Opti ID Admin > Security > MFA Policy:
{ "mfa_policy": { "enforcement": "required", "allowed_methods": ["totp", "webauthn"], "grace_period_days": 14, "remember_device_days": 30, "admin_override": false, "bypass_for_sso": true }}| Setting | Options | Description |
|---|---|---|
enforcement | disabled, optional, required | MFA requirement level |
allowed_methods | Array of method identifiers | Which MFA methods users can choose |
grace_period_days | 0–30 | Days before enforcement after policy change |
remember_device_days | 0–90 | Days a trusted device skips MFA. 0 means always require. |
admin_override | boolean | Whether org admins can exempt specific users |
bypass_for_sso | boolean | Skip Opti ID MFA when IdP handles MFA via SAML/OIDC |
Enrolling MFA via API
Section titled “Enrolling MFA via API”POST /api/v1/mfa/enrollAuthorization: Bearer {user-access-token}Content-Type: application/json
{ "method": "totp"}Response:
{ "method": "totp", "provisioning_uri": "otpauth://totp/Optimizely:jane@example.com?secret=BASE32SECRET&issuer=Optimizely", "secret": "BASE32SECRET", "qr_code_url": "https://id.optimizely.com/mfa/qr/{enrollment-id}"}Verifying MFA enrollment
Section titled “Verifying MFA enrollment”POST /api/v1/mfa/verifyAuthorization: Bearer {user-access-token}Content-Type: application/json
{ "method": "totp", "code": "123456"}Error codes
Section titled “Error codes”| Code | HTTP status | Description |
|---|---|---|
saml_invalid_signature | 401 | SAML assertion signature validation failed |
saml_expired_assertion | 401 | SAML assertion has expired |
saml_missing_attribute | 400 | Required SAML attribute not present |
oidc_invalid_token | 401 | OIDC token validation failed |
oidc_invalid_redirect | 400 | Redirect URI does not match registered URIs |
scim_duplicate_user | 409 | User with this email already exists |
scim_invalid_filter | 400 | SCIM filter syntax is invalid |
scim_rate_limited | 429 | Too many SCIM requests |
mfa_invalid_code | 401 | MFA verification code is incorrect |
session_expired | 401 | Session has timed out |
Related resources
Section titled “Related resources”- Opti ID and Optimizely One — Conceptual overview of the identity layer
- Manage Users and Permissions — How to set up users and roles
- In-Product Help API — Embedding docs in Optimizely products