# Scalekit Documentation Scalekit is an enterprise authentication platform for B2B SaaS applications that provides a complete auth stack for AI apps, including SSO (Single Sign-On), SCIM (directory sync), MCP (Model Context Protocol) server authentication, Agent Auth for AI agents, and full-stack authentication. The platform handles complex authentication protocols like SAML and OIDC, allowing developers to focus on building their products while Scalekit manages secure identity verification, user provisioning, and access control for enterprise customers. The Scalekit API is a RESTful API that manages organizations, users, connections, and authentication settings. Official SDKs are available for Node.js, Python, Go, and Java. All requests use HTTPS with OAuth 2.0 Client Credentials authentication. The platform operates in two separate environments (Development and Production) with base URLs like `https://{subdomain}.scalekit.dev` for development and `https://{subdomain}.scalekit.com` for production. ## SDK Installation and Client Initialization Install the Scalekit SDK and initialize the client with your API credentials from the Scalekit dashboard. ```bash # Node.js npm install @scalekit-sdk/node # Python pip install scalekit-sdk-python # Go go get -u github.com/scalekit-inc/scalekit-sdk-go # Java (Gradle) implementation "com.scalekit:scalekit-sdk-java:2.0.11" ``` ```javascript // Node.js - Initialize Scalekit client import { Scalekit } from "@scalekit-sdk/node"; const scalekit = new Scalekit( process.env.SCALEKIT_ENVIRONMENT_URL, process.env.SCALEKIT_CLIENT_ID, process.env.SCALEKIT_CLIENT_SECRET ); ``` ```python # Python - Initialize Scalekit client from scalekit import ScalekitClient import os scalekit_client = ScalekitClient( env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") ) ``` ## OAuth 2.0 Access Token Obtain an access token using OAuth 2.0 Client Credentials grant for API authentication. ```bash # Get access token via cURL curl https:///oauth/token \ -X POST \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id={client_id}' \ -d 'client_secret={client_secret}' \ -d 'grant_type=client_credentials' # Response: # { # "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6InNua181Ok4OTEyMjU2NiIsInR5cCI6IkpXVCJ9...", # "token_type": "Bearer", # "expires_in": 86399, # "scope": "openid" # } # Use token in API requests curl https:///api/v1/organizations \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {access_token}' ``` ## Full-Stack Authentication - Authorization URL Generate an authorization URL to redirect users to Scalekit's hosted sign-in page for login or signup flows. ```javascript // Node.js - Create authorization URL and redirect const redirectUri = 'http://localhost:3000/auth/callback'; const options = { scopes: ['openid', 'profile', 'email', 'offline_access'] }; const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options); // Generated URL: https:///oauth/authorize?response_type=code&client_id=skc_1234&scope=openid%20profile%20email%20offline_access&redirect_uri=... res.redirect(authorizationUrl); ``` ```python # Python - Create authorization URL from scalekit import AuthorizationUrlOptions redirect_uri = 'http://localhost:3000/auth/callback' options = AuthorizationUrlOptions( scopes=['openid', 'profile', 'email', 'offline_access'] ) authorization_url = scalekit_client.get_authorization_url(redirect_uri, options) return redirect(authorization_url) ``` ## Organizations API - Create Organization Create a new organization (tenant) in your environment with display name and optional external ID. ```javascript // Node.js - Create organization const organization = await scalekit.organization.createOrganization("Acme Corp", { externalId: "acme-123" }); console.log(organization.id); // org_xxx ``` ```python # Python - Create organization from scalekit import CreateOrganizationOptions options = CreateOrganizationOptions() options.external_id = "acme-123" organization = scalekit_client.organization.create_organization( "Acme Corp", options=options ) ``` ```bash # cURL - Create organization curl -X POST "https:///api/v1/organizations" \ -H "Authorization: Bearer {access_token}" \ -H "Content-Type: application/json" \ -d '{ "display_name": "Acme Corp", "external_id": "acme-123" }' ``` ## Organizations API - List and Get Organizations Retrieve a paginated list of organizations or get details for a specific organization. ```javascript // Node.js - List organizations with pagination const organizations = await scalekit.organization.listOrganization({ pageSize: 10 }); // Get specific organization const org = await scalekit.organization.getOrganization("org_123"); console.log(org.displayName); ``` ```python # Python - List and get organizations from scalekit import ListOrganizationOptions options = ListOrganizationOptions() options.page_size = 10 organizations = scalekit_client.organization.list_organizations(options=options) # Get single organization org = scalekit_client.organization.get_organization("org_123") ``` ## Organizations API - Update and Delete Update organization details or delete an organization from the environment. ```javascript // Node.js - Update organization const updated = await scalekit.organization.updateOrganization("org_123", { displayName: "Acme Corporation", externalId: "acme-updated" }); // Delete organization await scalekit.organization.deleteOrganization("org_123"); ``` ```go // Go - Update and delete organization organization, err := scalekitClient.Organization.UpdateOrganization( ctx, "org_123", &scalekit.UpdateOrganization{ DisplayName: "Acme Corporation", ExternalId: "acme-updated", }, ) err = scalekitClient.Organization.DeleteOrganization(ctx, "org_123") ``` ## Admin Portal Link Generation Generate a single-use admin portal URL (valid for 1 minute) allowing organization admins to configure SSO and SCIM settings. ```javascript // Node.js - Generate admin portal link with SSO and directory sync features const link = await scalekit.organization.generatePortalLink("org_123"); // With specific features enabled // Query params: ?features=sso&features=dir_sync ``` ```python # Python - Generate portal link link = scalekit_client.organization.generate_portal_link("org_123") print(link.url) # One-time use URL for admin configuration ``` ```java // Java - Generate portal link with features Link portalLink = scalekitClient .organizations() .generatePortalLink(organizationId, Arrays.asList(Feature.sso, Feature.dir_sync)); ``` ## Organization Settings - Toggle Features Enable or disable SSO and directory sync features for an organization. ```javascript // Node.js - Update organization settings const settings = { features: [ { name: 'sso', enabled: true }, { name: 'dir_sync', enabled: true } ] }; await scalekit.organization.updateOrganizationSettings('org_123', settings); ``` ```python # Python - Toggle organization features settings = [ {"name": "sso", "enabled": True}, {"name": "dir_sync", "enabled": True} ] scalekit_client.organization.update_organization_settings( organization_id='org_123', settings=settings ) ``` ## Connections API - List SSO Connections Retrieve SSO connections for an organization or by domain to manage enterprise identity provider integrations. ```javascript // Node.js - List connections by organization const connections = await scalekit.connection.listConnections(organizationId); // List connections by domain const connectionsByDomain = await scalekit.connection.listConnectionsByDomain("example.com"); ``` ```python # Python - List connections connections = scalekit_client.connection.list_connections(organization_id) # By domain response = scalekit_client.connection.list_connections_by_domain(domain="example.com") ``` ## Users API - Create Membership Add an existing user to an organization with specific roles and metadata. ```javascript // Node.js - Add user to organization with roles await scalekit.user.createMembership("org_123", "usr_123", { roles: ["admin"], metadata: { department: "engineering", location: "nyc-office" } }); ``` ```python # Python - Add user to organization resp, _ = scalekit_client.users.add_user_to_organization( organization_id="org_123", user_id="usr_123" ) ``` ```go // Go - Create membership with roles membership := &usersv1.CreateMembership{ Roles: []*usersv1.Role{{Name: "admin"}}, Metadata: map[string]string{ "department": "engineering", "location": "nyc-office", }, } resp, err := scalekitClient.User().CreateMembership( context.Background(), "org_123", "usr_123", membership, false) ``` ## Users API - Update and Delete Membership Update user roles within an organization or remove a user from an organization. ```python # Python - Update membership scalekit_client.users.update_membership( organization_id="org_123", user_id="usr_123", role="admin" ) # Delete membership (remove user from organization) response = scalekit_client.users.delete_membership( organization_id="org_123", user_id="usr_123" ) ``` ## Roles API - Create and Manage Roles Create custom roles with permissions for organization-level access control. ```javascript // Node.js - Create organization role with permissions await scalekit.role.createOrganizationRole("org_123", { name: "org_admin", displayName: "Org Admin", description: "Organization-scoped administrator role", extends: "base_role_name", // optional inheritance permissions: ["perm.read", "perm.write"] }); // List all organization roles const roles = await scalekit.role.listOrganizationRoles("org_123"); // Get specific role details const role = await scalekit.role.getOrganizationRole("org_123", "org_admin"); ``` ```python # Python - Create and manage roles from scalekit.v1.roles.roles_pb2 import CreateOrganizationRole role = CreateOrganizationRole( name="org_admin", display_name="Org Admin", description="Organization-scoped role", extends="base_role_name", permissions=["perm.read", "perm.write"] ) scalekit_client.roles.create_organization_role(org_id="org_123", role=role) # List roles res = scalekit_client.roles.list_organization_roles(org_id="org_123") ``` ## Roles API - Update and Delete Roles Modify existing roles or delete them with optional user reassignment. ```javascript // Node.js - Update role await scalekit.role.updateOrganizationRole("org_123", "org_admin", { displayName: "Org Admin (Updated)", description: "Updated org role description" }); // Delete role with user reassignment await scalekit.role.deleteOrganizationRole("org_123", "org_role_admin", "org_role_member"); ``` ```go // Go - Update and delete roles resp, err := scalekitClient.Role().UpdateOrganizationRole(ctx, "org_123", "org_admin", &rolesv1.UpdateRole{ DisplayName: "Org Admin (Updated)", Description: "Updated org role description", }) // Delete with reassignment err = scalekitClient.Role().DeleteOrganizationRole(ctx, "org_123", "org_role_admin", "org_role_member") ``` ## Agent Auth - Connected Accounts Create and manage connected accounts for third-party OAuth integrations (Gmail, Slack, Notion, etc.) to enable AI agents to act on behalf of users. ```python # Python - Create connected account for Gmail integration import scalekit.client from dotenv import load_dotenv import os load_dotenv() scalekit_client = scalekit.client.ScalekitClient( client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), env_url=os.getenv("SCALEKIT_ENV_URL"), ) actions = scalekit_client.actions # Create or retrieve user's connected Gmail account response = actions.get_or_create_connected_account( connection_name="gmail", identifier="user_123" # Your system's unique user ID ) connected_account = response.connected_account print(f'Connected account created: {connected_account.id}') # Generate authorization link if not active if connected_account.status != "ACTIVE": link_response = actions.get_authorization_link( connection_name="gmail", identifier="user_123" ) print(f"Authorization link: {link_response.link}") ``` ```javascript // Node.js - Manage connected accounts import { ScalekitClient } from '@scalekit-sdk/node'; const scalekit = new ScalekitClient( process.env.SCALEKIT_ENV_URL, process.env.SCALEKIT_CLIENT_ID, process.env.SCALEKIT_CLIENT_SECRET ); const { connectedAccounts, tools } = scalekit; // Create connected account const response = await connectedAccounts.getOrCreateConnectedAccount({ connector: 'gmail', identifier: 'user_123' }); // Get magic link for OAuth authorization if (response.connectedAccount?.status !== 'ACTIVE') { const linkResponse = await connectedAccounts.getMagicLinkForConnectedAccount({ connector: 'gmail', identifier: 'user_123' }); console.log('Authorization link:', linkResponse.link); } ``` ## Agent Auth - Fetch OAuth Tokens Retrieve OAuth access tokens and refresh tokens for connected accounts to make API calls on behalf of users. ```python # Python - Get OAuth tokens from connected account response = actions.get_connected_account( connection_name="gmail", identifier="user_123" ) connected_account = response.connected_account tokens = connected_account.authorization_details["oauth_token"] access_token = tokens["access_token"] refresh_token = tokens["refresh_token"] # Use access_token to call Gmail API on behalf of user # Scalekit automatically refreshes tokens when needed ``` ```javascript // Node.js - Extract OAuth tokens const accountResponse = await connectedAccounts.getConnectedAccountByIdentifier({ connector: 'gmail', identifier: 'user_123' }); const authDetails = accountResponse?.connectedAccount?.authorizationDetails; const accessToken = (authDetails && authDetails.details?.case === "oauthToken") ? authDetails.details.value?.accessToken : undefined; console.log('Access token:', accessToken); ``` ## Connected Accounts API - List and Search List all connected accounts with filtering options or search across accounts. ```bash # cURL - List connected accounts with filters curl -X GET "https:///api/v1/connected_accounts?organization_id=org_123&connector=gmail&page_size=10" \ -H "Authorization: Bearer {access_token}" # Search connected accounts curl -X GET "https:///api/v1/connected_accounts:search?query=user@example.com&page_size=30" \ -H "Authorization: Bearer {access_token}" ``` ## Execute Tool API Execute actions on third-party services using connected account credentials (send emails, create calendar events, etc.). ```bash # cURL - Execute a tool action curl -X POST "https:///api/v1/execute_tool" \ -H "Authorization: Bearer {access_token}" \ -H "Content-Type: application/json" \ -d '{ "tool_name": "gmail_send_email", "parameters": { "to": "recipient@example.com", "subject": "Hello from AI Agent", "body": "This email was sent by an AI agent using Scalekit." }, "connected_account_id": "ca_123" }' ``` ## MCP Server Authentication - Discovery Endpoint Implement the OAuth 2.1 protected resource discovery endpoint for MCP (Model Context Protocol) servers. ```javascript // Node.js (Express) - MCP discovery endpoint app.get('/.well-known/oauth-protected-resource', (req, res) => { res.json({ // Get from Scalekit dashboard > MCP servers > Your server > Metadata JSON "authorization_servers": [ "https:///resources/" ], "bearer_methods_supported": ["header"], "resource": "https://mcp.yourapp.com", "resource_documentation": "https://mcp.yourapp.com/docs", "scopes_supported": ["todo:read", "todo:write"] }); }); ``` ```python # Python (FastAPI) - MCP discovery endpoint from fastapi import FastAPI from fastapi.responses import JSONResponse app = FastAPI() @app.get("/.well-known/oauth-protected-resource") async def get_oauth_protected_resource(): return JSONResponse({ "authorization_servers": [ "https:///resources/" ], "bearer_methods_supported": ["header"], "resource": "https://mcp.yourapp.com", "resource_documentation": "https://mcp.yourapp.com/docs", "scopes_supported": ["todo:read", "todo:write"] }) ``` ## MCP Server - Token Validation Validate access tokens from MCP clients using the Scalekit SDK to secure your MCP server endpoints. ```javascript // Node.js - MCP token validation middleware import { Scalekit } from '@scalekit-sdk/node'; const scalekit = new Scalekit( process.env.SCALEKIT_ENVIRONMENT_URL, process.env.SCALEKIT_CLIENT_ID, process.env.SCALEKIT_CLIENT_SECRET ); const RESOURCE_ID = 'https://your-mcp-server.com'; const METADATA_ENDPOINT = 'https://your-mcp-server.com/.well-known/oauth-protected-resource'; // WWW-Authenticate header for unauthorized responses const WWWHeader = { HeaderKey: 'WWW-Authenticate', HeaderValue: `Bearer realm="OAuth", resource_metadata="${METADATA_ENDPOINT}"` }; // Middleware to validate bearer tokens async function validateMCPToken(req, res, next) { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { res.set(WWWHeader.HeaderKey, WWWHeader.HeaderValue); return res.status(401).json({ error: 'Missing bearer token' }); } const token = authHeader.substring(7); try { const claims = await scalekit.validateToken(token, { audience: RESOURCE_ID }); req.user = claims; next(); } catch (error) { res.set(WWWHeader.HeaderKey, WWWHeader.HeaderValue); return res.status(401).json({ error: 'Invalid token' }); } } ``` ## Enterprise SSO - Generate Authorization URL Create an SSO authorization URL to redirect users to their enterprise identity provider (Okta, Entra ID, JumpCloud, etc.). ```javascript // Node.js - SSO authorization URL with organization hint const redirectUri = 'http://localhost:3000/auth/callback'; const options = { scopes: ['openid', 'profile', 'email'], organizationId: 'org_123' // Hint to route to correct IdP }; const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options); res.redirect(authorizationUrl); ``` ```python # Python - SSO authorization URL from scalekit import AuthorizationUrlOptions redirect_uri = 'http://localhost:3000/auth/callback' options = AuthorizationUrlOptions( scopes=['openid', 'profile', 'email'], organization_id='org_123' ) authorization_url = scalekit_client.get_authorization_url(redirect_uri, options) ``` ## API Clients - Machine-to-Machine Authentication Create and manage API clients for organization-level machine-to-machine authentication. ```python # Python - List and create organization API clients org_id = 'org_123' # List existing clients response = scalekit_client.m2m_client.list_organization_clients( organization_id=org_id, page_size=30 ) for client in response.clients: print(f"Client ID: {client.id}, Name: {client.name}") # Create new API client (secret returned only once) new_client = scalekit_client.m2m_client.create_organization_client( organization_id=org_id, name="Backend Service", scopes=["read:users", "write:users"] ) print(f"Client secret (save this!): {new_client.secret}") ``` ## Webhooks - Event Handling Register webhook endpoints to receive real-time events for user provisioning, SSO connections, and directory changes. ```python # Python - Webhook event handler example from flask import Flask, request, jsonify import hmac import hashlib app = Flask(__name__) WEBHOOK_SECRET = "your_webhook_secret" @app.route('/webhooks/scalekit', methods=['POST']) def handle_webhook(): # Verify webhook signature signature = request.headers.get('X-Scalekit-Signature') payload = request.get_data() expected_sig = hmac.new( WEBHOOK_SECRET.encode(), payload, hashlib.sha256 ).hexdigest() if not hmac.compare_digest(signature, expected_sig): return jsonify({'error': 'Invalid signature'}), 401 event = request.json event_type = event.get('event_type') # Handle different event types if event_type == 'user.created': user = event['data']['user'] print(f"New user created: {user['email']}") elif event_type == 'user.updated': user = event['data']['user'] print(f"User updated: {user['id']}") elif event_type == 'directory.user_created': # SCIM provisioning event user = event['data'] print(f"Directory user provisioned: {user['email']}") return jsonify({'received': True}), 200 ``` ## Error Handling Handle API errors with standard HTTP status codes and detailed error responses. ```javascript // Node.js - Error handling pattern try { const organization = await scalekit.organization.getOrganization("org_invalid"); } catch (error) { if (error.status === 404) { console.error("Organization not found"); } else if (error.status === 401) { console.error("Authentication failed - check credentials"); } else if (error.status === 429) { console.error("Rate limit exceeded - retry after delay"); } else { console.error("API error:", error.message); // Error response format: // { // "code": 16, // "message": "Token empty", // "details": [{ "@type": "...", "error_code": "UNAUTHENTICATED" }] // } } } ``` ## Summary Scalekit provides a comprehensive authentication platform designed for B2B SaaS applications with three primary integration patterns: **Full-Stack Authentication** for complete hosted auth flows with session management, **Modular SSO/SCIM** for adding enterprise features to existing auth systems, and **Agent Auth/MCP** for securing AI agent and MCP server integrations. The platform abstracts complex identity protocols (SAML, OIDC, OAuth 2.1) while providing fine-grained access control through organizations, roles, and permissions. Common integration patterns include using the Admin Portal for self-service SSO configuration by enterprise customers, implementing webhook handlers for real-time user provisioning via SCIM, managing connected accounts for AI agents to access third-party services, and securing MCP servers with OAuth 2.1 token validation. The SDKs (Node.js, Python, Go, Java) provide consistent interfaces across all endpoints with built-in token management and error handling, making it straightforward to integrate Scalekit into existing application architectures.