Skip to content

IdP Configuration API Reference

Complete API reference for Partner Identity Provider (IdP) configuration endpoints. These endpoints allow partners to configure OIDC-based single sign-on for their users.

API Overview

The IdP Configuration API is part of the Partner Admin API and requires API key authentication. Each partner app can have one IdP configuration for OIDC-based SSO.

Base URL

Environment Base URL
Production https://api.contio.ai
Beta https://beta.api.contio.ai

Authentication

All IdP configuration endpoints require authentication using your Partner API Key and Client ID:

Header Description
X-API-Key Your partner app's API key
X-Client-ID Your partner app's client ID
const headers = {
  'X-API-Key': process.env.CONTIO_API_KEY,
  'X-Client-ID': process.env.CONTIO_CLIENT_ID,
  'Content-Type': 'application/json'
};

Rate Limits

Admin API endpoints are rate-limited to 500 requests per 5 minutes (approximately 100 requests per minute). When you exceed the rate limit, the API returns a 429 Too Many Requests response.

Endpoints

Create IdP Configuration

Creates a new OIDC identity provider configuration for the authenticated partner app.

Endpoint: POST /v1/partner/admin/idp

Request Body:

{
  "name": "Acme Corporate SSO",
  "discovery_url": "https://login.acme.com/.well-known/openid-configuration",
  "idp_client_id": "contio-integration-prod",
  "idp_client_secret": "secret-from-idp-admin-console",
  "scopes": ["openid", "email", "profile"],
  "claim_mappings": {
    "email": "email",
    "name": "name"
  },
  "mode": "strict",
  "allowed_email_domains": ["acme.com", "acme.co.uk"]
}

Request Fields:

Field Type Required Description
name string Yes Display name for the IdP configuration (1-255 characters)
discovery_url string Yes OIDC discovery endpoint URL (must be HTTPS)
idp_client_id string Yes OAuth Client ID from your Identity Provider. Not your Contio Partner client_id.
idp_client_secret string Yes OAuth Client Secret from your Identity Provider. Not your Contio Partner client_secret. Encrypted at rest.
scopes string[] No OIDC scopes to request. Default: ["openid", "email", "profile"]
claim_mappings object No Map IdP claims to Contio fields. Default: {"email": "email", "name": "name"}
mode string Yes Domain validation mode: strict or partner_managed
allowed_email_domains string[] Conditional Required if mode=strict; optional if mode=partner_managed

OAuth Connection Required

Users must establish a connection to your partner app via OAuth before they can use SSO. SSO provides authentication convenience, not user provisioning.

Response (201 Created):

{
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "partner_app_id": "98765432-10ab-cdef-0123-456789abcdef",
  "name": "Acme Corporate SSO",
  "type": "oidc",
  "discovery_url": "https://login.acme.com/.well-known/openid-configuration",
  "idp_client_id": "contio-integration-prod",
  "scopes": ["openid", "email", "profile"],
  "claim_mappings": {
    "email": "email",
    "name": "name"
  },
  "mode": "strict",
  "allowed_email_domains": ["acme.com", "acme.co.uk"],
  "is_active": true,
  "issuer": "https://login.acme.com",
  "authorization_endpoint": "https://login.acme.com/oauth2/authorize",
  "token_endpoint": "https://login.acme.com/oauth2/token",
  "userinfo_endpoint": "https://login.acme.com/oauth2/userinfo",
  "jwks_uri": "https://login.acme.com/.well-known/jwks.json",
  "discovery_last_fetched_at": "2024-01-01T00:00:00Z",
  "created_at": "2024-01-01T00:00:00Z",
  "updated_at": "2024-01-01T00:00:00Z"
}

Error Responses:

Status Error Code Description
400 invalid_request_body Request body validation failed
400 invalid_idp_credentials You provided your Contio Partner credentials instead of your IdP credentials
400 invalid_idp_credentials You provided your Contio Partner credentials instead of your IdP credentials
400 invalid_idp_credentials You provided your Contio Partner credentials instead of your IdP credentials
400 invalid_idp_credentials You provided your Contio Partner credentials instead of your IdP credentials
400 invalid_idp Public IdP (Google, Microsoft consumer, Zoho) not allowed
400 domain_is_generic Generic email domain not allowed
400 strict_mode_requires_domains Strict mode requires at least one allowed domain
400 discovery_fetch_failed Failed to fetch OIDC discovery document
401 unauthorized Invalid or missing API credentials
409 idp_config_exists IdP configuration already exists for this partner
409 domain_already_claimed Domain claimed by another partner

Example:

// Note: IdP configuration methods coming soon to SDK
// For now, use direct API calls:

const response = await fetch('https://api.contio.ai/v1/partner/admin/idp', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.CONTIO_API_KEY,
    'X-Client-ID': process.env.CONTIO_CLIENT_ID,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Company SSO',
    discovery_url: 'https://company.okta.com/.well-known/openid-configuration',
    idp_client_id: '0oa1234567890abcdef',
    idp_client_secret: process.env.IDP_CLIENT_SECRET,
    mode: 'strict',
    allowed_email_domains: ['company.com']
  })
});

if (!response.ok) {
  const error = await response.json();
  console.error('Failed to create IdP config:', error.code, error.error);
  throw new Error(error.error);
}

const config = await response.json();
console.log('Created IdP config:', config.id);

Get IdP Configuration

Retrieves the current IdP configuration for the authenticated partner app.

Endpoint: GET /v1/partner/admin/idp

Response (200 OK):

{
  "id": "01234567-89ab-cdef-0123-456789abcdef",
  "partner_app_id": "98765432-10ab-cdef-0123-456789abcdef",
  "name": "Acme Corporate SSO",
  "type": "oidc",
  "discovery_url": "https://login.acme.com/.well-known/openid-configuration",
  "idp_client_id": "contio-integration-prod",
  "scopes": ["openid", "email", "profile"],
  "claim_mappings": {
    "email": "email",
    "name": "name"
  },
  "mode": "strict",
  "allowed_email_domains": ["acme.com", "acme.co.uk"],
  "is_active": true,
  "issuer": "https://login.acme.com",
  "authorization_endpoint": "https://login.acme.com/oauth2/authorize",
  "token_endpoint": "https://login.acme.com/oauth2/token",
  "userinfo_endpoint": "https://login.acme.com/oauth2/userinfo",
  "jwks_uri": "https://login.acme.com/.well-known/jwks.json",
  "discovery_last_fetched_at": "2024-01-01T00:00:00Z",
  "created_at": "2024-01-01T00:00:00Z",
  "updated_at": "2024-01-01T00:00:00Z"
}

Error Responses:

Status Error Code Description
401 unauthorized Invalid or missing API credentials
404 idp_config_not_found No IdP configuration exists for this partner

Example:

const response = await fetch('https://api.contio.ai/v1/partner/admin/idp', {
  method: 'GET',
  headers: {
    'X-API-Key': process.env.CONTIO_API_KEY,
    'X-Client-ID': process.env.CONTIO_CLIENT_ID
  }
});

if (response.status === 404) {
  console.log('No IdP configuration found');
  return null;
}

const config = await response.json();
console.log('IdP config:', config.name, '- Active:', config.is_active);

Update IdP Configuration

Updates the IdP configuration for the authenticated partner app. All fields are optional; only include fields you want to change.

Endpoint: PUT /v1/partner/admin/idp

Request Body:

{
  "name": "Updated SSO Name",
  "discovery_url": "https://new-idp.acme.com/.well-known/openid-configuration",
  "idp_client_id": "new-client-id",
  "idp_client_secret": "new-client-secret",
  "scopes": ["openid", "email", "profile", "groups"],
  "claim_mappings": {
    "email": "email",
    "name": "displayName"
  },
  "mode": "partner_managed",
  "allowed_email_domains": ["acme.com", "subsidiary.com"],
  "is_active": true
}

Request Fields:

Field Type Required Description
name string No Display name (1-255 characters)
discovery_url string No OIDC discovery endpoint URL
idp_client_id string No OAuth Client ID from your Identity Provider
idp_client_secret string No OAuth Client Secret from your Identity Provider
scopes string[] No OIDC scopes to request
claim_mappings object No Claim to field mappings
mode string No Domain validation mode: strict or partner_managed
allowed_email_domains string[] No Allowed email domains
is_active boolean No Enable or disable the IdP configuration

Response (200 OK):

Returns the updated IdP configuration (same schema as GET response).

Error Responses:

Status Error Code Description
400 invalid_request_body Request body validation failed
400 invalid_idp_credentials You provided your Contio Partner credentials instead of your IdP credentials
400 invalid_idp Public IdP not allowed
400 domain_is_generic Generic email domain not allowed
400 strict_mode_requires_domains Strict mode requires domains
400 discovery_fetch_failed Failed to fetch discovery document
401 unauthorized Invalid or missing API credentials
404 idp_config_not_found No IdP configuration exists
409 domain_already_claimed Domain claimed by another partner

Example:

// Disable the IdP configuration temporarily
const response = await fetch('https://api.contio.ai/v1/partner/admin/idp', {
  method: 'PUT',
  headers: {
    'X-API-Key': process.env.CONTIO_API_KEY,
    'X-Client-ID': process.env.CONTIO_CLIENT_ID,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    is_active: false
  })
});

const config = await response.json();
console.log('IdP config active:', config.is_active);

Delete IdP Configuration

Deletes the IdP configuration for the authenticated partner app. This action cannot be undone.

Endpoint: DELETE /v1/partner/admin/idp

Response (204 No Content):

No response body on success.

Error Responses:

Status Error Code Description
401 unauthorized Invalid or missing API credentials
404 idp_config_not_found No IdP configuration exists

Example:

const response = await fetch('https://api.contio.ai/v1/partner/admin/idp', {
  method: 'DELETE',
  headers: {
    'X-API-Key': process.env.CONTIO_API_KEY,
    'X-Client-ID': process.env.CONTIO_CLIENT_ID
  }
});

if (response.status === 204) {
  console.log('IdP configuration deleted successfully');
} else if (response.status === 404) {
  console.log('No IdP configuration to delete');
}

Data Schemas

IdPConfigResponse

The complete IdP configuration object returned by GET and POST/PUT endpoints.

Field Type Description
id string (UUID) Unique identifier for the IdP configuration
partner_app_id string (UUID) ID of the partner app this configuration belongs to
name string Display name for the IdP configuration
type string IdP type, always "oidc"
discovery_url string OIDC discovery endpoint URL
idp_client_id string OAuth Client ID from your Identity Provider (secret is never returned)
scopes string[] OIDC scopes requested during authentication
claim_mappings object Map of Contio fields to IdP claim names
mode string Domain validation mode: "strict" or "partner_managed"
allowed_email_domains string[] List of allowed email domains (may be empty)
is_active boolean Whether the IdP configuration is active
issuer string Cached IdP issuer from discovery document
authorization_endpoint string Cached authorization endpoint URL
token_endpoint string Cached token endpoint URL
userinfo_endpoint string Cached userinfo endpoint URL
jwks_uri string Cached JWKS endpoint URL
discovery_last_fetched_at string (ISO 8601) When discovery document was last fetched
created_at string (ISO 8601) When the configuration was created
updated_at string (ISO 8601) When the configuration was last updated

ClaimMappings

The claim_mappings object maps Contio user fields to IdP claim names. This allows customization for IdPs that use non-standard claim names.

Contio Field Purpose Required Default IdP Claim
email User's email address for account linking Yes email
name User's display name No name
given_name User's first name No given_name
family_name User's last name No family_name

Standard OIDC Example:

{
  "email": "email",
  "name": "name"
}

Azure AD Example:

{
  "email": "preferred_username",
  "name": "name",
  "given_name": "given_name",
  "family_name": "family_name"
}

Custom IdP Example:

{
  "email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
  "name": "displayName",
  "given_name": "firstName",
  "family_name": "lastName"
}

DomainValidationMode

The mode field controls how user email domains are validated during SSO.

Mode Description
strict Requires allowed_email_domains to be specified with at least one domain. Only users with matching email domains can authenticate. Generic domains are blocked and cross-partner exclusivity is enforced. All users require prior OAuth connection.
partner_managed Domain list is optional. If provided, same validation rules apply. If empty, the partner's IdP controls access entirely. All users require prior OAuth connection.

OAuth Connection Required

All users must establish a connection to your partner app via OAuth before they can use SSO. SSO provides authentication convenience using corporate IdP credentials, not user provisioning.

ErrorResponse

All error responses follow this format:

{
  "code": "error_code",
  "error": "Human-readable error message",
  "request_id": "unique-request-id"
}
Field Type Description
code string Machine-readable error code
error string Human-readable error description
request_id string Unique identifier for the request (useful for support)

Error Reference

Complete list of error codes for IdP configuration endpoints.

Error Code HTTP Status Description Recovery Action
invalid_request_body 400 Request body failed validation Check required fields and data types
invalid_idp 400 Public IdP (Google, Microsoft consumer, Zoho) not allowed Use a corporate/organizational IdP
domain_is_generic 400 Generic email domain (gmail.com, etc.) in allowed_email_domains Use corporate domains only
strict_mode_requires_domains 400 Strict mode selected but no allowed_email_domains provided Add at least one allowed email domain
discovery_fetch_failed 400 Could not fetch OIDC discovery document Verify discovery_url is correct and accessible
unauthorized 401 Invalid or missing API key/client ID Check X-API-Key and X-Client-ID headers
idp_config_not_found 404 No IdP configuration exists for this partner Create an IdP configuration first
idp_config_exists 409 IdP configuration already exists Use PUT to update or DELETE to remove
domain_already_claimed 409 Email domain claimed by another partner Contact Contio support if you own this domain
internal_server_error 500 Unexpected server error Retry the request; contact support if persistent

Partner SSO Flow Endpoints

These public endpoints handle the SSO authentication flow. They are documented here for reference but are typically not called directly by partner applications.

Get Partner SSO Info

Returns partner branding and SSO configuration status for landing pages.

Endpoint: GET /v1/partner/sso/info/{slug}

Path Parameters:

Parameter Type Description
slug string Partner app slug

Response (200 OK):

{
  "slug": "acme",
  "name": "Acme Inc",
  "co_brand_name": "Acme Meetings",
  "co_brand_logo_url": "https://cdn.acme.com/logo.png",
  "has_idp_config": true,
  "is_active": true
}

Rate Limit: 30 requests per minute per IP address.

Initiate SSO Flow

Starts the SSO authentication flow for a partner's identity provider.

Endpoint: GET /v1/partner/sso/initiate

Query Parameters:

Parameter Type Required Description
slug string Yes Partner app slug
target string No Target platform: web (default) or desktop
auto boolean No If true, redirect directly to IdP

Response (200 OK):

{
  "authorization_url": "https://login.acme.com/oauth2/authorize?...",
  "session_id": "sess_abc123"
}

Response (302 Found): When auto=true, redirects directly to the authorization URL.

SSO Callback

Handles the OIDC callback from the partner's identity provider. This endpoint is called by the IdP after user authentication.

Endpoint: GET /v1/partner/sso/callback

Query Parameters:

Parameter Type Description
code string Authorization code from IdP
state string State parameter for session validation
error string Error code if authentication failed
error_description string Error description if authentication failed

Response: Redirects to the target application (web or desktop deep link) after processing.

Session Status

Returns the current status of a partner SSO session for polling.

Endpoint: GET /v1/partner/sso/session/{session_id}

Response (200 OK):

{
  "status": "pending",
  "user_id": null,
  "target": "desktop",
  "error": null
}

Status Values:

Status Description
pending Session is active, waiting for authentication
expired Session has expired (10 minute timeout)
not_found Session not found or already processed

SDK Support

SDK Methods Coming Soon

IdP configuration methods are not yet available in the TypeScript SDK. Use direct API calls as shown in the examples above. SDK support will be added in a future release.

When SDK support is available, the methods will follow this pattern:

// Future SDK usage (not yet available)
const { admin } = ContioPartnerSDK.forAdmin({
  apiKey: process.env.CONTIO_API_KEY,
  clientId: process.env.CONTIO_CLIENT_ID
});

// Create IdP configuration
const config = await admin.idp.create({
  name: 'Company SSO',
  discovery_url: 'https://company.okta.com/.well-known/openid-configuration',
  idp_client_id: 'client-id-from-your-idp',
  idp_client_secret: 'client-secret-from-your-idp',
  mode: 'strict',
  allowed_email_domains: ['company.com']
});

// Get IdP configuration
const config = await admin.idp.get();

// Update IdP configuration
const updated = await admin.idp.update({ is_active: false });

// Delete IdP configuration
await admin.idp.delete();

Next Steps