API & SDK Reference: Complete API endpoints and SDK documentation for Node.js, Python, Go, and Java
---
# DOCUMENT BOUNDARY
---
# User authentication flow
> Learn how Scalekit routes users through authentication based on login method and organization SSO policies.
The user’s authentication journey on the hosted login page can differ based on the **login method** they choose and the **organization policies** configured in Scalekit. ## Organization policies [Section titled “Organization policies”](#organization-policies) Organizations can enforce Enterprise SSO for their users. An organization must create an enabled [SSO connection](/authenticate/auth-methods/enterprise-sso/) and add [organization domains](/authenticate/auth-methods/enterprise-sso/#identify-and-enforce-sso-for-organization-users). Scalekit uses **Home Realm Discovery (HRD)** to determine whether a user’s email domain matches a configured organization domain. When a match is found, the user is routed to that organization’s SSO identity provider. **Examples** * A user tries to log in as `user@samecorp.com` on the hosted login page. If `samecorp.com` is registered as an organization domain with SSO enabled, the user is redirected to that organization’s IdP to complete authentication. * A user tries to log in with Google as `user@samecorp.com` on the hosted login page. If `samecorp.com` is registered as an organization domain with SSO enabled, the user is redirected to that organization’s IdP after returning from Google. ## Login method–specific behavior [Section titled “Login method–specific behavior”](#login-methodspecific-behavior) Scalekit allows users to choose different login methods on the hosted login page. The timing of organization domain checks differs slightly by method, but the rules remain consistent. ### Social login [Section titled “Social login”](#social-login) * User authenticates with a social IdP (e.g., Google, GitHub). * Scalekit evaluates the user’s email after social auth completes. * Home Realm Discovery (HRD) checks whether the email domain matches an organization domain. * **Domain match:** User is redirected to the organization’s SSO IdP. * **No match:** Authentication completes. This ensures that enterprise users must complete SSO authentication even if they initially choose social login. ### Passkey login [Section titled “Passkey login”](#passkey-login) * User authenticates using a passkey. * Authentication succeeds immediately. * Scalekit performs Home Realm Discovery (HRD) to check the email domain. * **Domain match:** User is redirected to SSO. * **No match:** Authentication completes. Passkeys authenticate the user, but do not override organization SSO policy. ### Email-based login [Section titled “Email-based login”](#email-based-login) * User enters their email address. * Home Realm Discovery (HRD) runs **before authentication** to check the email domain. * **Domain match:** User is redirected to SSO. * **No match:** Scalekit performs OTP or magic link verification, then authentication completes. ### Authentication flow [Section titled “Authentication flow”](#authentication-flow) This diagram shows the different variations of user’s authentication journey on the hosted login page. *** ## Enterprise SSO Trust model [Section titled “Enterprise SSO Trust model”](#enterprise-sso-trust-model) Most enterprise identity providers (IdPs) like Okta or Microsoft Entra do not prove that a user actually controls the email inbox they sign in with. They only assert an email address in the SAML/OIDC token. Because of this, when a user logs in via Enterprise SSO, Scalekit does not automatically treat that SSO connection as a trusted source of email ownership. Since Scalekit cannot be sure that the SSO user truly owns the email address, the user is taken through an email ownership check (magic link or OTP) to prove control of that inbox. After the user successfully verifies their email, that SSO connection is marked as a verified channel for that specific user, and they do not need to verify email ownership again on subsequent logins via the same connection. If you want an Enterprise SSO connection to be treated as a trusted provider for a specific domain, you can assign one or more domains to the organization. Then, for users logging in via that Enterprise SSO connection whose email address matches one of the configured domains, Scalekit skips additional email ownership verification. | SSO trust case | Example | Result | | -------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | | Trusted SSO | Org has added `acmecorp.com` in organization domain. User authenticates as `user@acmecorp.com` with organization SSO. | Email ownership trusted | | Untrusted SSO | Org has added `acmecorp.com` in organization domain and user authenticates as `user@foocorp.com` with organization SSO. | Email ownership not trusted → Additional verification required | *** ## Forcing SSO from your application [Section titled “Forcing SSO from your application”](#forcing-sso-from-your-application) Your app can override Home Realm Discovery (HRD) by passing `organization_id` or `connection_id` in the authentication request ↗ to Scalekit. When you do this: * Scalekit skips HRD and redirects the user directly to the specified SSO IdP. * After SSO authentication completes, Scalekit checks whether the user’s email domain matches one of the organization domains configured on that SSO connection. * **Domain match**: authentication completes. * **No match**: Scalekit requires additional verification (OTP or magic link) before completing authentication. ## IdP‑initiated SSO [Section titled “IdP‑initiated SSO”](#idpinitiated-sso) In IdP‑initiated SSO, authentication starts at the identity provider instead of your application or the hosted login page. After the IdP authenticates the user and redirects to Scalekit, Scalekit evaluates email ownership trust: * If the user’s email domain matches one of the organization domains configured on the SSO connection, authentication completes. * If the email domain does not match, Scalekit requires additional verification (OTP or magic link) before completing authentication. This workflow ensures IdP‑initiated flows follow the same email ownership and trust guarantees as app‑initiated SSO *** ## Account linking [Section titled “Account linking”](#account-linking) ### What happens [Section titled “What happens”](#what-happens) Scalekit maintains a single user record per email address. For example, if a user first authenticates with passwordless login (magic link/OTP) and later uses Google or Enterprise SSO, Scalekit links both identities to the same user record. These identities are stored on the user object for your app to read if needed. This avoids duplicate users when people switch authentication methods. ### Why it is safe [Section titled “Why it is safe”](#why-it-is-safe) Scalekit only treats an SSO IdP as a trusted source of email ownership when: * the authenticated email domain matches one of the organization domains configured on the SSO connection, or * the user has previously proven email ownership via magic link or OTP. Because the organization has proven domain ownership, and/or the user has proven inbox control, emails from that SSO connection are treated as valid. This prevents attackers from linking identities unless email ownership has been verified through trusted mechanisms.
---
# DOCUMENT BOUNDARY
---
# Implement enterprise SSO
> How to implement enterprise SSO for your application
Enterprise single sign-on (SSO) enables users to authenticate using their organization’s identity provider (IdP), such as Okta, Azure AD, or Google Workspace. [After completing the quickstart](/authenticate/fsa/quickstart/), follow this guide to implement SSO for an organization, streamline admin onboarding, enforce login requirements, and validate your configuration. 1. ## Enable SSO for the organization [Section titled “Enable SSO for the organization”](#enable-sso-for-the-organization) When a user signs up for your application, Scalekit automatically creates an organization and assigns an admin role to the user. Provide an option in your user interface to enable SSO for the organization or workspace. Here’s how you can do that with Scalekit. Use the following SDK method to activate SSO for the organization: * Node.js Enable SSO ```javascript const settings = { features: [ { name: 'sso', enabled: true, } ], }; await scalekit.organization.updateOrganizationSettings( '', // Get this from the idToken or accessToken settings ); ``` * Python Enable SSO ```python settings = [ { "name": "sso", "enabled": True } ] scalekit.organization.update_organization_settings( organization_id='', # Get this from the idToken or accessToken settings=settings ) ``` * Java Enable SSO ```java OrganizationSettingsFeature featureSSO = OrganizationSettingsFeature.newBuilder() .setName("sso") .setEnabled(true) .build(); updatedOrganization = scalekitClient.organizations() .updateOrganizationSettings(organizationId, List.of(featureSSO)); ``` * Go Enable SSO ```go settings := OrganizationSettings{ Features: []Feature{ { Name: "sso", Enabled: true, }, }, } organization, err := sc.Organization().UpdateOrganizationSettings(ctx, organizationId, settings) if err != nil { // Handle error } ``` You can also enable this from the [organization settings](/authenticate/fsa/user-management-settings/) in the Scalekit dashboard. 2. ## Enable admin portal for enterprise customer onboarding [Section titled “Enable admin portal for enterprise customer onboarding”](#enable-admin-portal-for-enterprise-customer-onboarding) After SSO is enabled for that organization, provide a method for configuring a SSO connection with the organization’s identity provider. Scalekit offers two primary approaches: * Generate a link to the admin portal from the Scalekit dashboard and share it with organization admins via your usual channels. * Or embed the admin portal in your application in an inline frame so administrators can configure their IdP without leaving your app. [See how to onboard enterprise customers ](/sso/guides/onboard-enterprise-customers/) 3. ## Identify and enforce SSO for organization users [Section titled “Identify and enforce SSO for organization users”](#identify-and-enforce-sso-for-organization-users) Administrators typically register organization-owned domains through the admin portal. When a user attempts to sign in with an email address matching a registered domain, they are automatically redirected to their organization’s designated identity provider for authentication. This is also known as **Home Realm Discovery**. **Organization domains** automatically route users to the correct SSO connection based on their email address. When a user signs in with an email domain that matches a registered organization domain, Scalekit redirects them to that organization’s SSO provider and enforces SSO login. For example, if an organization registers `megacorp.org`, any user signing in with an `joe@megacorp.org` email address is redirected to Megacorp’s SSO provider.  Navigate to **Dashboard > Organizations** and select the target organization > **Overview** > **Organization Domains** section to register organization domains. 4. ## Test your SSO integration [Section titled “Test your SSO integration”](#test-your-sso-integration) Scalekit offers a “Test Organization” feature that enables SSO flow validation without requiring test accounts from your customers’ identity providers. To quickly test the integration, enter an email address using the domains `joe@example.com` or `jane@example.org`. This will trigger a redirect to the IdP simulator, which serves as the test organization’s identity provider for authentication. For a comprehensive step-by-step walkthrough, refer to the [Test SSO integration guide](/sso/guides/test-sso/).
---
# DOCUMENT BOUNDARY
---
# Add passkeys login method
> Enable passkey authentication for your users
Passkeys replace passwords with biometric authentication (fingerprint, face recognition) or device PINs. Built on FIDO® standards (WebAuthn and CTAP), passkeys offer superior security by eliminating phishing and credential stuffing vulnerabilities, while also providing a seamless one-tap login experience. Unlike traditional authentication methods, passkeys sync across devices, removing the need for multiple enrollments and providing better recovery options when devices are lost. Your [existing Scalekit integration](/authenticate/fsa/quickstart) already supports passkeys. To implement, enable passkeys in the Scalekit dashboard and leverage Scalekit’s built-in user passkey registration functionality. 1. ## Enable passkeys in the Scalekit dashboard [Section titled “Enable passkeys in the Scalekit dashboard”](#enable-passkeys-in-the-scalekit-dashboard) Go to Scalekit Dashboard > Authentication > Auth methods > Passkeys and click “Enable”  2. ## Manage passkey registration [Section titled “Manage passkey registration”](#manage-passkey-registration) Let users manage passkeys just by redirecting them to Scalekit from your app (usually through a button in your app that says “Manage passkeys”), or building your own UI. #### Using Scalekit UI [Section titled “Using Scalekit UI”](#using-scalekit-ui) To enable users to register and manage their passkeys, redirect them to the Scalekit passkey registration page.  Construct the URL by appending `/ui/profile/passkeys` to your Scalekit environment URL Passkey Registration URL ```js /ui/profile/passkeys ``` This opens a page where users can: * Register new passkeys * Remove existing passkeys * View their registered passkeys #### In your own UI [Section titled “In your own UI”](#in-your-own-ui) If you prefer to create a custom user interface for passkey management, Scalekit offers comprehensive APIs that enable you to build a personalized experience. These APIs allow you to list registered passkeys, rename them, and remove them entirely. However registration of passkeys is only supported through the Scalekit UI. * Node.js List user's passkeys ```js // : fetch from Access Token or ID Token after identity verification const res = await fetch( '/api/v1/webauthn/credentials?user_id=', { headers: { Authorization: 'Bearer ' } } ); const data = await res.json(); console.log(data); ``` Rename a passkey ```js // : obtained from list response (id of each passkey) await fetch('/api/v1/webauthn/credentials/', { method: 'PATCH', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' }, body: JSON.stringify({ display_name: '' }) }); ``` Remove a passkey ```js // : obtained from list response (id of each passkey) await fetch('/api/v1/webauthn/credentials/', { method: 'DELETE', headers: { Authorization: 'Bearer ' } }); ``` * Python List user's passkeys ```python import requests # : fetch from access token or ID token after identity verification r = requests.get( '/api/v1/webauthn/credentials', params={'user_id': ''}, headers={'Authorization': 'Bearer '} ) print(r.json()) ``` Rename a passkey ```python import requests # : obtained from list response (id of each passkey) requests.patch( '/api/v1/webauthn/credentials/', json={'display_name': ''}, headers={'Authorization': 'Bearer '} ) ``` Remove a passkey ```python import requests # : obtained from list response (id of each passkey) requests.delete( '/api/v1/webauthn/credentials/', headers={'Authorization': 'Bearer '} ) ``` * Java List user's passkeys ```java var client = java.net.http.HttpClient.newHttpClient(); // : fetch from Access Token or ID Token after identity verification var req = java.net.http.HttpRequest.newBuilder( java.net.URI.create("/api/v1/webauthn/credentials?user_id=") ) .header("Authorization", "Bearer ") .GET().build(); var res = client.send(req, java.net.http.HttpResponse.BodyHandlers.ofString()); System.out.println(res.body()); ``` Rename a passkey ```java var client = java.net.http.HttpClient.newHttpClient(); var body = "{\"display_name\":\"\"}"; // : obtained from list response (id of each passkey) var req = java.net.http.HttpRequest.newBuilder( java.net.URI.create("/api/v1/webauthn/credentials/") ) .header("Authorization", "Bearer ") .header("Content-Type","application/json") .method("PATCH", java.net.http.HttpRequest.BodyPublishers.ofString(body)) .build(); client.send(req, java.net.http.HttpResponse.BodyHandlers.discarding()); ``` Remove a passkey ```java var client = java.net.http.HttpClient.newHttpClient(); // : obtained from list response (id of each passkey) var req = java.net.http.HttpRequest.newBuilder( java.net.URI.create("/api/v1/webauthn/credentials/") ) .header("Authorization", "Bearer ") .DELETE().build(); client.send(req, java.net.http.HttpResponse.BodyHandlers.discarding()); ``` * Go List user's passkeys ```go // imports: net/http, io, fmt // : fetch from access token or ID token after identity verification req, _ := http.NewRequest("GET", "/api/v1/webauthn/credentials?user_id=", nil) req.Header.Set("Authorization", "Bearer ") resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() b, _ := io.ReadAll(resp.Body) fmt.Println(string(b)) ``` Rename a passkey ```go // imports: net/http, bytes payload := bytes.NewBufferString(`{"display_name":""}`) // : obtained from list response (id of each passkey) req, _ := http.NewRequest("PATCH", "/api/v1/webauthn/credentials/", payload) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer ") http.DefaultClient.Do(req) ``` Remove a passkey ```go // imports: net/http // : obtained from list response (id of each passkey) req, _ := http.NewRequest("DELETE", "/api/v1/webauthn/credentials/", nil) req.Header.Set("Authorization", "Bearer ") http.DefaultClient.Do(req) ``` 3. ## Users can log in with passkeys [Section titled “Users can log in with passkeys”](#users-can-log-in-with-passkeys) Users who have registered passkeys can log in with them. This time when login page shows, users can select “Passkey” as the authentication method.  During sign-up, you’ll continue to use established authentication methods like [verification codes, magic links](/authenticate/auth-methods/passwordless/) or [social logins](/authenticate/auth-methods/social-logins/). Once a user is registered, they can then add passkeys as an additional, convenient login option.
---
# DOCUMENT BOUNDARY
---
# Sign in with magic link or Email OTP
> Enable passwordless sign-in with email verification codes or magic links
Configure Magic Link & OTP to enable passwordless authentication for your application. After completing the [quickstart guide](/authenticate/fsa/quickstart/), set up email verification codes or magic links so users can sign in without passwords. Switch between those passwordless methods without modifying any code: | Method | How it works | Best for | | ------------------------------ | ---------------------------------------------------------------- | -------------------------------------------- | | Verification code | Users receive a one-time code via email and enter it in your app | Applications requiring explicit verification | | Magic link | Users click a link in their email to authenticate | Quick, frictionless sign-in | | Magic link + Verification code | Users choose either method | Maximum flexibility and user choice | ## Configure magic link or OTP [Section titled “Configure magic link or OTP”](#configure-magic-link-or-otp) In the Scalekit dashboard, go to **Authentication > Auth methods > Magic Link & OTP**  1. ### Select authentication method [Section titled “Select authentication method”](#select-authentication-method) Choose one of three methods: * **Verification code** - Users enter a 6-digit code sent to their email * **Magic link** - Users click a link in their email to authenticate * **Magic link + Verification code** - Users can choose either method 2. ### Set expiry period [Section titled “Set expiry period”](#set-expiry-period) Configure how long verification codes and magic links remain valid: * **Default**: 300 seconds (5 minutes) * **Range**: 60 to 3600 seconds * **Recommendation**: 300 seconds balances security and usability ## Enforce same browser origin [Section titled “Enforce same browser origin”](#enforce-same-browser-origin) When enforcing same browser origin, users are required to complete magic link authentication within the same browser where they initiated the login process. This security feature is particularly recommended for applications dealing with sensitive data or financial transactions, as it adds an extra layer of protection against potential unauthorized access attempts. **Example scenario**: A healthcare app where a user requests a magic link on their laptop. If someone intercepts the email and tries to open it on a different device, the authentication fails. ## Regenerate credentials on resend [Section titled “Regenerate credentials on resend”](#regenerate-credentials-on-resend) When a user requests a new Magic Link or Email OTP, the system generates a fresh code or link while automatically invalidating the previous one. This approach is recommended for all applications as a critical security measure to prevent potential misuse of compromised credentials. **Example scenario**: A user requests a verification code but doesn’t receive it. They request a new code. With this setting enabled, the first code becomes invalid, preventing unauthorized access if the original email was intercepted.
---
# DOCUMENT BOUNDARY
---
# Add social login to your app
> Implement authentication with Google, Microsoft, GitHub, and other social providers
First, complete the [quickstart guide](/authenticate/fsa/quickstart/) to integrate Scalekit auth into your application. Scalekit natively supports OAuth 2.0, enabling you to easily configure social login providers that will automatically appear as authentication options on your login page. 1. ## Configure social login providers [Section titled “Configure social login providers”](#configure-social-login-providers) Google login is pre-configured in all development environments for simplified testing. You can integrate additional social login providers by setting up your own connection credentials with each provider. Navigate to **Authentication** > **Auth Methods** > **Social logins** in your dashboard to configure these settings ### Google Enable users to sign in with their Google accounts using OAuth 2.0 [Setup →](/guides/integrations/social-connections/google) ### GitHub Allow users to authenticate using their GitHub credentials [Setup →](/guides/integrations/social-connections/github) ### Microsoft Integrate Microsoft accounts for seamless user authentication [Setup →](/guides/integrations/social-connections/microsoft) ### GitLab Enable GitLab-based authentication for your application [Setup →](/guides/integrations/social-connections/gitlab) ### LinkedIn Let users sign in with their LinkedIn accounts using OAuth 2.0 [Setup →](/guides/integrations/social-connections/linkedin) ### Salesforce Enable Salesforce-based authentication for your application [Setup →](/guides/integrations/social-connections/salesforce) 2. ## Test the social connection [Section titled “Test the social connection”](#test-the-social-connection) After configuration, test the social connection by clicking on “Test Connection” in the dashboard. You will be redirected to the provider’s consent screen to authorize access. A summary table will show the information that will be sent to your app.  ## Access social login options on your login page [Section titled “Access social login options on your login page”](#access-social-login-options-on-your-login-page) Your application now supports social logins. Begin the [login process](/authenticate/fsa/implement-login/) to experience the available social login options. Users can authenticate using providers like Google, GitHub, Microsoft, and any others you have set up.
---
# DOCUMENT BOUNDARY
---
# SDKs
> Ready-to-use SDKs for Node.js, Python, Go, and Java to integrate Scalekit into your app
2.6.0 • Updated 2 weeks ago Full-featured, TypeScript-friendly SDK for modern Node.js based applications TypeScript & ESM ready Express, NestJS, Next.js compatible [Get Started →](/sdks/node/) v2.9.0 • Updated 2 weeks ago Async-first design with complete type hints and Pydantic validation Pydantic v2 validated FastAPI, Django, Flask compatible [Get Started →](/sdks/python/) v2.6.0 • Updated 1 month ago Zero-dependency, idiomatic Go SDK for high-performance services Thread-safe & lightweight Gin, Echo, Chi compatible [Get Started →](/sdks/go/) v2.1.1 • Updated 5 days ago Enterprise-ready SDK with seamless Spring Boot integration Spring Boot integrated Maven Central published [Get Started →](/sdks/java/) Official Expo SDK with React Hooks for enterprise-ready mobile authentication React Hooks & TypeScript OAuth 2.0 with PKCE [Get Started →](/sdks/expo/)
---
# DOCUMENT BOUNDARY
---
# Authenticate with Scalekit API
> Learn how to authenticate your server applications with Scalekit API using OAuth 2.0 Client Credentials flow
This guide explains how to authenticate your server applications with the Scalekit API using the OAuth 2.0 Client Credentials flow. After reading this guide, you’ll be able to: * Generate an access token using your API credentials * Make authenticated API requests to Scalekit endpoints * Handle authentication errors appropriately This guide targets developers who need to integrate Scalekit services into their backend applications or automate tasks through API calls. ## Before you begin [Section titled “Before you begin”](#before-you-begin) Before starting the authentication process, ensure you have set up your Scalekit account and obtained your API credentials. ## Step 1: Configure your environment [Section titled “Step 1: Configure your environment”](#step-1-configure-your-environment) Store your API credentials securely as environment variables: Environment variables ```sh 1 SCALEKIT_ENVIRONMENT_URL="" 2 SCALEKIT_CLIENT_ID="" 3 SCALEKIT_CLIENT_SECRET="" ``` ## Step 2: Request an access token [Section titled “Step 2: Request an access token”](#step-2-request-an-access-token) To authenticate your API requests, you must first obtain an access token from the Scalekit authorization server. ### Token endpoint URL [Section titled “Token endpoint URL”](#token-endpoint-url) Token endpoint URL ```sh 1 https:///oauth/token ``` ### Send a token request [Section titled “Send a token request”](#send-a-token-request) Choose your preferred method to request an access token: * cURL ```bash 1 curl -X POST \ 2 "https:///oauth/token" \ 3 -H "Content-Type: application/x-www-form-urlencoded" \ 4 -d "grant_type=client_credentials" \ 5 -d "client_id=" \ 6 -d "client_secret=" \ 7 -d "scope=openid profile email" ``` * Node.js ```javascript 1 import axios from 'axios'; 2 3 const config = { 4 clientId: process.env.SCALEKIT_CLIENT_ID, 5 clientSecret: process.env.SCALEKIT_CLIENT_SECRET, 6 tokenUrl: `${process.env.SCALEKIT_ENVIRONMENT_URL}/oauth/token`, 7 scope: 'openid email profile', 8 }; 9 10 async function getClientCredentialsToken() { 11 try { 12 const params = new URLSearchParams(); 13 params.append('grant_type', 'client_credentials'); 14 params.append('client_id', config.clientId); 15 params.append('client_secret', config.clientSecret); 16 17 if (config.scope) { 18 params.append('scope', config.scope); 19 } 20 21 const response = await axios.post(config.tokenUrl, params, { 22 headers: { 23 'Content-Type': 'application/x-www-form-urlencoded', 24 }, 25 }); 26 27 const { access_token, expires_in } = response.data; 28 console.log(`Token acquired successfully. Expires in ${expires_in} seconds.`); 29 return access_token; 30 } catch (error) { 31 console.error('Error getting client credentials token:', error); 32 throw new Error('Failed to obtain access token'); 33 } 34 } ``` * Python ```python 1 import os 2 import json 3 import requests 4 5 def get_access_token(): 6 """Request an access token using client credentials.""" 7 headers = {"Content-Type": "application/x-www-form-urlencoded"} 8 params = { 9 "grant_type": "client_credentials", 10 "client_id": os.environ['SCALEKIT_CLIENT_ID'], 11 "client_secret": os.environ['SCALEKIT_CLIENT_SECRET'] 12 } 13 oauth_token_url = os.environ['SCALEKIT_ENVIRONMENT_URL'] 14 15 response = requests.post(oauth_token_url, headers=headers, data=params, verify=True) 16 access_token = response.json().get('access_token') 17 return access_token ``` ### Understand the token response [Section titled “Understand the token response”](#understand-the-token-response) When your request succeeds, the server returns a JSON response with the following fields: | Field | Description | | -------------- | ----------------------------------------------------- | | `access_token` | The token you’ll use to authenticate API requests | | `token_type` | The token type (always Bearer for this flow) | | `expires_in` | Token validity period in seconds (typically 24 hours) | | `scope` | The authorized scopes for this token | Example token response: Token response ```json 1 { 2 "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6InNua181Ok4OTEyMjU2NiIsInR5cCI6IkpXVCJ9...", 3 "token_type": "Bearer", 4 "expires_in": 86399, 5 "scope": "openid" 6 } ``` ## Step 3: Make authenticated API requests [Section titled “Step 3: Make authenticated API requests”](#step-3-make-authenticated-api-requests) After obtaining an access token, add it to the `Authorization` header in your API requests. * cURL ```bash 1 curl --request GET "https:///api/v1/organizations" \ 2 -H "Content-Type: application/json" \ 3 -H "Authorization: Bearer " ``` * Node.js (axios) ```javascript 1 async function makeAuthenticatedRequest(endpoint) { 2 try { 3 const access_token = await getClientCredentialsToken(); 4 const url = `${process.env.SCALEKIT_ENVIRONMENT_URL}${endpoint}`; 5 6 const response = await axios.get(url, { 7 headers: { 8 Authorization: `Bearer ${access_token}`, 9 }, 10 }); 11 12 console.log('API Response:', response.data); 13 return response.data; 14 } catch (error) { 15 console.error('Error making authenticated request:', error); 16 throw error; 17 } 18 } ``` * Python (requests) ```python 1 import os 2 import json 3 import requests 4 5 env_url = os.environ['SCALEKIT_ENVIRONMENT_URL'] 6 7 def get_access_token(): 8 """Request an access token using client credentials.""" 9 headers = {"Content-Type": "application/x-www-form-urlencoded"} 10 params = { 11 "grant_type": "client_credentials", 12 "client_id": os.environ['SCALEKIT_CLIENT_ID'], 13 "client_secret": os.environ['SCALEKIT_CLIENT_SECRET'] 14 } 15 16 response = requests.post( 17 url=f"{env_url}/oauth/token", 18 headers=headers, 19 data=params, 20 verify=True) 21 22 access_token = response.json().get('access_token') 23 return access_token 24 25 def get_organizations(get_orgs_endpoint): 26 """Retrieve all organizations for the specified environment.""" 27 access_token = get_access_token() 28 headers = {"Authorization": f"Bearer {access_token}"} 29 30 response = requests.get( 31 url=f"{env_url}/{get_orgs_endpoint}", 32 headers=headers) 33 return response ``` Example API response ```json 1 { 2 "next_page_token": "", 3 "total_size": 3, 4 "organizations": [ 5 { 6 "id": "org_64444217115541813", 7 "create_time": "2025-03-20T13:55:46.690Z", 8 "update_time": "2025-03-21T05:55:03.416772Z", 9 "display_name": "Looney Corp", 10 "region_code": "US", 11 "external_id": "my_unique_id", 12 "metadata": {} 13 } 14 ], 15 "prev_page_token": "" 16 } ``` ## Common authentication issues [Section titled “Common authentication issues”](#common-authentication-issues) | Issue | Possible cause | Solution | | ---------------- | ------------------------ | ------------------------------- | | 401 Unauthorized | Invalid or expired token | Generate a new access token | | 403 Forbidden | Insufficient permissions | Check client credentials scopes | | Connection error | Network or server issue | Retry with exponential backoff | ## Next steps [Section titled “Next steps”](#next-steps) Now that you can authenticate with the Scalekit API, you can: * Browse the complete API reference to discover available endpoints * Create a token management service to handle token refreshing * Implement error handling strategies for production use
---
# DOCUMENT BOUNDARY
---
# UI events from the embedded admin portal
> Learn how to listen for and handle UI events from the embedded admin portal, such as SSO connection status and session expiration.
The embedded admin portal emits browser events that allow your application to respond to configuration changes made by organization admins. Use these events to provide real-time feedback, update your UI, sync configuration state, or trigger workflows in your application. Common use cases include displaying success notifications when SSO is configured, refreshing authentication settings after directory sync is enabled, or prompting users to re-authenticate when their admin portal session expires. ## Listening to admin portal events [Section titled “Listening to admin portal events”](#listening-to-admin-portal-events) Add an event listener to your parent window to receive events from the embedded admin portal iframe: ```js 1 window.addEventListener('message', (event) => { 2 // Security: Always validate the event origin matches your Scalekit environment 3 if (event.origin !== 'https://your-env.scalekit.com') { 4 return; // Ignore events from untrusted sources 5 } 6 7 // Check if this is a valid admin portal event 8 if (event.data && event.data.event_type) { 9 const { event_type, organization_id, data } = event.data; 10 11 // Handle specific event types 12 switch (event_type) { 13 case 'ORGANIZATION_SSO_ENABLED': 14 // Show success notification, refresh SSO settings, etc. 15 showNotification('SSO enabled successfully'); 16 break; 17 18 case 'PORTAL_SESSION_EXPIRY': 19 // Prompt user to refresh the admin portal 20 promptSessionRefresh(); 21 break; 22 23 default: 24 console.log('Received event:', event.data); 25 } 26 } 27 }); ``` Security requirement The domain of your parent window must be listed in **Dashboard > API Config > Redirect URIs** for the admin portal to emit events. Always validate `event.origin` to ensure events come from your trusted Scalekit environment URL. *** ## SSO events [Section titled “SSO events”](#sso-events) ### `ORGANIZATION_SSO_ENABLED` [Section titled “ORGANIZATION\_SSO\_ENABLED”](#organization_sso_enabled) Fires when an organization admin successfully enables a Single Sign-On connection in the admin portal. ORGANIZATION\_SSO\_ENABLED ```json 1 { 2 "event_type": "ORGANIZATION_SSO_ENABLED", 3 "object": "connection", 4 "organization_id": "org_4010340X34236531", // Organization that enabled SSO 5 "message": "Single sign-on connection enabled successfully", 6 "data": { 7 "connection_type": "SSO", 8 "id": "conn_4256075523X312", // Connection ID for API calls 9 "type": "OIDC", // Protocol: OIDC or SAML 10 "provider": "OKTA", // Identity provider configured 11 "enabled": true 12 } 13 } ``` | Field | Type | Description | | ---------------------- | ------- | ------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.connection_type` | string | Type of connection (SSO) | | `data.id` | string | Unique identifier for the connection | | `data.type` | string | Protocol type (e.g., OIDC, SAML) | | `data.provider` | string | Identity provider name | | `data.enabled` | boolean | Indicates if the connection is enabled | ### `ORGANIZATION_SSO_DISABLED` [Section titled “ORGANIZATION\_SSO\_DISABLED”](#organization_sso_disabled) Fires when an organization admin disables their Single Sign-On connection in the admin portal. ORGANIZATION\_SSO\_DISABLED ```json 1 { 2 "event_type": "ORGANIZATION_SSO_DISABLED", 3 "object": "connection", 4 "organization_id": "org_4010340X34236531", // Organization that disabled SSO 5 "message": "Single sign-on connection disabled successfully", 6 "data": { 7 "connection_type": "SSO", 8 "id": "conn_4256075523X312", // Connection ID that was disabled 9 "type": "OIDC", // Protocol: OIDC or SAML 10 "provider": "OKTA", // Identity provider that was configured 11 "enabled": false 12 } 13 } ``` | Field | Type | Description | | ---------------------- | ------- | ------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.connection_type` | string | Type of connection (SSO) | | `data.id` | string | Unique identifier for the connection | | `data.type` | string | Protocol type (e.g., OIDC, SAML) | | `data.provider` | string | Identity provider name | | `data.enabled` | boolean | Indicates if the connection is enabled | ## Session events [Section titled “Session events”](#session-events) ### `PORTAL_LOAD_SUCCESS` [Section titled “PORTAL\_LOAD\_SUCCESS”](#portal_load_success) Fires when the admin portal session is created and loaded successfully. Use this event to display the portal iframe and confirm readiness to users. PORTAL\_LOAD\_SUCCESS ```json 1 { 2 "event_type": "PORTAL_LOAD_SUCCESS", 3 "object": "session", 4 "message": "The admin portal loaded successfully", 5 "organization_id": "org_43982563588440584", 6 "data": { 7 "expiry": "2025-02-28T12:40:35.911Z" // ISO 8601 timestamp when session expires 8 } 9 } ``` | Field | Type | Description | | ----------------- | ------ | ---------------------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.expiry` | string | ISO 8601 timestamp indicating when the session will expire | ### `PORTAL_LOAD_FAILURE` [Section titled “PORTAL\_LOAD\_FAILURE”](#portal_load_failure) Fires when the admin portal session failed to load. Use this to prompt users that the session has failed to load. PORTAL\_LOAD\_FAILURE ```json 1 { 2 "event_type": "PORTAL_LOAD_FAILURE", 3 "object": "session", 4 "message": "The admin portal failed to load", 5 "data": { 6 "error_code": "SESSION_EXPIRED" // error code indicating why the session load failed 7 } 8 } ``` | Field | Type | Description | | ----------------- | ------ | ------------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `message` | string | Human-readable message describing the event | | `data.error_code` | string | Error code indicating why the session load failed | ### `PORTAL_SESSION_WARNING` [Section titled “PORTAL\_SESSION\_WARNING”](#portal_session_warning) Fires when the admin portal session is about to expire (typically 5 minutes before expiration). Use this to prompt users to save their work or refresh their session. PORTAL\_SESSION\_WARNING ```json 1 { 2 "event_type": "PORTAL_SESSION_WARNING", 3 "object": "session", 4 "message": "The admin portal session will expire in 5 minutes", 5 "organization_id": "org_43982563588440584", 6 "data": { 7 "expiry": "2025-02-28T12:40:35.911Z" // ISO 8601 timestamp when session expires 8 } 9 } ``` | Field | Type | Description | | ----------------- | ------ | ---------------------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.expiry` | string | ISO 8601 timestamp indicating when the session will expire | ### `PORTAL_SESSION_EXPIRY` [Section titled “PORTAL\_SESSION\_EXPIRY”](#portal_session_expiry) Fires when the admin portal session has expired. Use this to hide the admin portal iframe and prompt users to re-authenticate. PORTAL\_SESSION\_EXPIRY ```json 1 { 2 "event_type": "PORTAL_SESSION_EXPIRY", 3 "object": "session", 4 "message": "The admin portal session has expired", 5 "organization_id": "org_43982563588440584", 6 "data": { 7 "expiry": "2025-02-28T12:40:35.911Z" // ISO 8601 timestamp when session expired 8 } 9 } ``` | Field | Type | Description | | ----------------- | ------ | ------------------------------------------------------ | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.expiry` | string | ISO 8601 timestamp indicating when the session expired | ## Directory events [Section titled “Directory events”](#directory-events) ### `ORGANIZATION_DIRECTORY_ENABLED` [Section titled “ORGANIZATION\_DIRECTORY\_ENABLED”](#organization_directory_enabled) Fires when an organization admin successfully configures and enables SCIM directory provisioning in the admin portal. ORGANIZATION\_DIRECTORY\_ENABLED ```json 1 { 2 "event_type": "ORGANIZATION_DIRECTORY_ENABLED", 3 "object": "directory", 4 "organization_id": "org_45716217859670289", // Organization that enabled directory sync 5 "message": "SCIM Provisioning enabled successfully", 6 "data": { 7 "directory_type": "SCIM", // Directory protocol type 8 "id": "dir_45716228982964495", // Directory connection ID for API calls 9 "provider": "MICROSOFT_AD", // Identity provider: OKTA, AZURE_AD, GOOGLE, etc. 10 "enabled": true 11 } 12 } ``` | Field | Type | Description | | --------------------- | ------- | ---------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.directory_type` | string | Type of directory synchronization (SCIM) | | `data.id` | string | Unique identifier for the directory connection | | `data.provider` | string | Identity provider name | | `data.enabled` | boolean | Indicates if the directory sync is enabled | ### `ORGANIZATION_DIRECTORY_DISABLED` [Section titled “ORGANIZATION\_DIRECTORY\_DISABLED”](#organization_directory_disabled) Fires when an organization admin disables SCIM directory provisioning in the admin portal. ORGANIZATION\_DIRECTORY\_DISABLED ```json 1 { 2 "event_type": "ORGANIZATION_DIRECTORY_DISABLED", 3 "object": "directory", 4 "organization_id": "org_45716217859670289", // Organization that disabled directory sync 5 "message": "SCIM Provisioning disabled successfully", 6 "data": { 7 "directory_type": "SCIM", // Directory protocol type 8 "id": "dir_45716228982964495", // Directory connection ID that was disabled 9 "provider": "MICROSOFT_AD", // Identity provider that was configured 10 "enabled": false 11 } 12 } ``` | Field | Type | Description | | --------------------- | ------- | ---------------------------------------------- | | `event_type` | string | The type of event being triggered | | `object` | string | The object type associated with the event | | `organization_id` | string | Unique identifier for the organization | | `message` | string | Human-readable message describing the event | | `data.directory_type` | string | Type of directory synchronization (SCIM) | | `data.id` | string | Unique identifier for the directory connection | | `data.provider` | string | Identity provider name | | `data.enabled` | boolean | Indicates if the directory sync is enabled | ## Complete event handler Example [Section titled “Complete event handler ”](#complete-event-handler-) Here’s a complete example showing how to handle all admin portal events in a production application: Complete admin portal event handler ```js 1 // Initialize event handling for the admin portal 2 function initAdminPortalEventHandling(scalekitEnvironmentUrl) { 3 window.addEventListener('message', (event) => { 4 // Security: Validate event origin 5 if (event.origin !== scalekitEnvironmentUrl) { 6 return; 7 } 8 9 if (!event.data || !event.data.event_type) { 10 return; 11 } 12 13 const { event_type, organization_id, data, message } = event.data; 14 15 // Log all events for debugging 16 console.log('[Admin Portal Event]', { event_type, organization_id, data }); 17 18 switch (event_type) { 19 case 'ORGANIZATION_SSO_ENABLED': 20 handleSSOEnabled(organization_id, data); 21 break; 22 23 case 'ORGANIZATION_SSO_DISABLED': 24 handleSSODisabled(organization_id, data); 25 break; 26 27 case 'ORGANIZATION_DIRECTORY_ENABLED': 28 handleDirectoryEnabled(organization_id, data); 29 break; 30 31 case 'ORGANIZATION_DIRECTORY_DISABLED': 32 handleDirectoryDisabled(organization_id, data); 33 break; 34 35 case 'PORTAL_LOAD_SUCCESS': 36 handlePortalLoadSuccess(data.expiry); 37 break; 38 39 case 'PORTAL_LOAD_FAILURE': 40 handlePortalLoadFailure(data.error_code); 41 break; 42 43 case 'PORTAL_SESSION_WARNING': 44 handleSessionWarning(data.expiry); 45 break; 46 47 case 'PORTAL_SESSION_EXPIRY': 48 handleSessionExpiry(); 49 break; 50 51 default: 52 console.warn('Unknown event type:', event_type); 53 } 54 }); 55 } 56 57 function handleSSOEnabled(orgId, data) { 58 // Show success notification 59 showToast('success', `SSO enabled successfully with ${data.provider}`); 60 61 // Sync configuration to your backend 62 fetch('/api/organizations/${orgId}/sync-sso', { 63 method: 'POST', 64 headers: { 'Content-Type': 'application/json' }, 65 body: JSON.stringify({ connectionId: data.id, provider: data.provider }) 66 }); 67 68 // Update UI to reflect SSO is active 69 updateOrganizationUI(orgId, { ssoEnabled: true }); 70 } 71 72 function handlePortalLoadSuccess(expiryTime) { 73 const expiryDate = new Date(expiryTime); 74 console.log('[Admin Portal] Loaded successfully, session expires at', expiryDate); 75 76 // Update UI to show the portal is ready 77 document.getElementById('admin-portal-iframe').style.display = 'block'; 78 } 79 80 function handlePortalLoadFailure(errorCode) { 81 console.error('[Admin Portal] Failed to load, error code:', errorCode); 82 83 // Hide the iframe and show an error message to the user 84 document.getElementById('admin-portal-iframe').style.display = 'none'; 85 86 showModal({ 87 title: 'Portal failed to load', 88 message: errorCode === 'SESSION_EXPIRED' 89 ? 'Your session has expired. Please refresh to continue.' 90 : `The admin portal could not be loaded (${errorCode}). Please try again.`, 91 action: { 92 label: 'Refresh Page', 93 onClick: () => window.location.reload() 94 } 95 }); 96 } 97 98 function handleSessionWarning(expiryTime) { 99 const expiryDate = new Date(expiryTime); 100 const minutesLeft = Math.round((expiryDate - new Date()) / 60000); 101 102 showNotification({ 103 type: 'warning', 104 message: `Your admin session will expire in ${minutesLeft} minutes`, 105 action: { 106 label: 'Refresh Session', 107 onClick: () => window.location.reload() 108 } 109 }); 110 } 111 112 function handleSessionExpiry() { 113 // Hide the admin portal iframe 114 document.getElementById('admin-portal-iframe').style.display = 'none'; 115 116 // Show message to user 117 showModal({ 118 title: 'Session Expired', 119 message: 'Your admin portal session has expired. Please refresh to continue.', 120 action: { 121 label: 'Refresh Page', 122 onClick: () => window.location.reload() 123 } 124 }); 125 } 126 127 // Initialize when your app loads 128 initAdminPortalEventHandling('https://your-env.scalekit.com'); ```
---
# DOCUMENT BOUNDARY
---
# BigQuery (Service Account)
Connect to BigQuery using a GCP service account for server-to-server authentication without user login.  Supports authentication: Service Account ## Create a Connection [Section titled “Create a Connection”](#create-a-connection) In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** > **Create Connection**. Find **BigQuery (Service Account)** and click **Create**. That’s it — no OAuth credentials or redirect URIs needed. BigQuery Service Account uses server-to-server authentication handled entirely through your GCP service account credentials. ## Create a Connected Account [Section titled “Create a Connected Account”](#create-a-connected-account) To connect a BigQuery account programmatically, you need a GCP service account JSON key. Here’s how to get one: 1. ### Create a GCP service account * Go to [Google Cloud Console](https://console.cloud.google.com) → **IAM & Admin** → **Service Accounts**. * Click **+ Create Service Account**, enter a name and description, and click **Create and Continue**. * Grant the service account the **BigQuery Data Viewer**, **BigQuery Data Editor**, and **BigQuery Job User** roles, then click **Done**. 2. ### Enable the BigQuery API * In [Google Cloud Console](https://console.cloud.google.com), go to **APIs & Services** → **Library**. * Search for **BigQuery API** and click **Enable**.  3. ### Download the service account JSON key * In the Service Accounts list, click on your service account. * Go to the **Keys** tab → **Add Key** → **Create new key**. * Select **JSON** and click **Create**. The key file downloads automatically. * Use the contents of this file as the `service_account_json` value when creating a connected account. ## Usage [Section titled “Usage”](#usage) ## Tool list [Section titled “Tool list”](#tool-list) ## `bigqueryserviceaccount_get_dataset` [Section titled “bigqueryserviceaccount\_get\_dataset”](#bigqueryserviceaccount_get_dataset) Retrieve metadata for a specific BigQuery dataset, including location, description, labels, access controls, and creation/modification times. | Name | Type | Required | Description | | ------------ | ------ | -------- | --------------------------------- | | `dataset_id` | string | Yes | The ID of the dataset to retrieve | ## `bigqueryserviceaccount_get_job` [Section titled “bigqueryserviceaccount\_get\_job”](#bigqueryserviceaccount_get_job) Retrieve the status and configuration of a BigQuery job by its job ID. Use this to poll for completion of an async query job. | Name | Type | Required | Description | | ---------- | ------ | -------- | ------------------------------------------------------------ | | `job_id` | string | Yes | The ID of the job to retrieve | | `location` | string | No | Geographic location where the job was created, e.g. US or EU | ## `bigqueryserviceaccount_get_model` [Section titled “bigqueryserviceaccount\_get\_model”](#bigqueryserviceaccount_get_model) Retrieve metadata for a specific BigQuery ML model, including model type, feature columns, label columns, and training run details. | Name | Type | Required | Description | | ------------ | ------ | -------- | ------------------------------------------ | | `dataset_id` | string | Yes | The ID of the dataset containing the model | | `model_id` | string | Yes | The ID of the model to retrieve | ## `bigqueryserviceaccount_get_query_results` [Section titled “bigqueryserviceaccount\_get\_query\_results”](#bigqueryserviceaccount_get_query_results) Retrieve the results of a completed BigQuery query job. Supports pagination via page tokens. Use after polling Get Job until status is DONE. | Name | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------------------------------ | | `job_id` | string | Yes | The ID of the completed query job | | `location` | string | No | Geographic location where the job was created, e.g. US or EU | | `max_results` | integer | No | Maximum number of rows to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page of results | | `timeout_ms` | integer | No | Maximum milliseconds to wait if the query has not yet completed | ## `bigqueryserviceaccount_get_routine` [Section titled “bigqueryserviceaccount\_get\_routine”](#bigqueryserviceaccount_get_routine) Retrieve the definition and metadata of a specific BigQuery routine (stored procedure or UDF), including its arguments, return type, and body. | Name | Type | Required | Description | | ------------ | ------ | -------- | -------------------------------------------- | | `dataset_id` | string | Yes | The ID of the dataset containing the routine | | `routine_id` | string | Yes | The ID of the routine to retrieve | ## `bigqueryserviceaccount_get_table` [Section titled “bigqueryserviceaccount\_get\_table”](#bigqueryserviceaccount_get_table) Retrieve metadata and schema for a specific BigQuery table or view, including column names, types, descriptions, and table properties. | Name | Type | Required | Description | | ------------ | ------ | -------- | ------------------------------------------ | | `dataset_id` | string | Yes | The ID of the dataset containing the table | | `table_id` | string | Yes | The ID of the table or view to retrieve | ## `bigqueryserviceaccount_list_datasets` [Section titled “bigqueryserviceaccount\_list\_datasets”](#bigqueryserviceaccount_list_datasets) List all BigQuery datasets in the project. Supports filtering by label and pagination. | Name | Type | Required | Description | | ------------- | ------- | -------- | ----------------------------------------------------------------- | | `all` | boolean | No | If true, includes hidden datasets in the results | | `filter` | string | No | Label filter expression to restrict results, e.g. labels.env:prod | | `max_results` | integer | No | Maximum number of datasets to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | ## `bigqueryserviceaccount_list_jobs` [Section titled “bigqueryserviceaccount\_list\_jobs”](#bigqueryserviceaccount_list_jobs) List BigQuery jobs in the project. Supports filtering by state and projection, and pagination. | Name | Type | Required | Description | | -------------- | ------- | -------- | -------------------------------------------------------------------------------------------------- | | `all_users` | boolean | No | If true, returns jobs for all users in the project; otherwise returns only the current user’s jobs | | `max_results` | integer | No | Maximum number of jobs to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | | `projection` | string | No | Controls the fields returned: minimal (default) or full | | `state_filter` | string | No | Filter jobs by state: done, pending, or running | ## `bigqueryserviceaccount_list_models` [Section titled “bigqueryserviceaccount\_list\_models”](#bigqueryserviceaccount_list_models) List all BigQuery ML models in a dataset, including their model type, training status, and creation time. | Name | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------------------- | | `dataset_id` | string | Yes | The ID of the dataset to list models from | | `max_results` | integer | No | Maximum number of models to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | ## `bigqueryserviceaccount_list_routines` [Section titled “bigqueryserviceaccount\_list\_routines”](#bigqueryserviceaccount_list_routines) List all stored procedures and user-defined functions (UDFs) in a BigQuery dataset. | Name | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------------------------------ | | `dataset_id` | string | Yes | The ID of the dataset to list routines from | | `filter` | string | No | Filter expression to restrict results, e.g. routineType:SCALAR\_FUNCTION | | `max_results` | integer | No | Maximum number of routines to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | ## `bigqueryserviceaccount_list_table_data` [Section titled “bigqueryserviceaccount\_list\_table\_data”](#bigqueryserviceaccount_list_table_data) Read rows directly from a BigQuery table without writing a SQL query. Supports pagination, row offset, and field selection. | Name | Type | Required | Description | | ----------------- | ------- | -------- | ---------------------------------------------------------------------------- | | `dataset_id` | string | Yes | The ID of the dataset containing the table | | `max_results` | integer | No | Maximum number of rows to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | | `selected_fields` | string | No | Comma-separated list of fields to return; if omitted all fields are returned | | `start_index` | integer | No | Zero-based row index to start reading from | | `table_id` | string | Yes | The ID of the table to read rows from | ## `bigqueryserviceaccount_list_tables` [Section titled “bigqueryserviceaccount\_list\_tables”](#bigqueryserviceaccount_list_tables) List all tables and views in a BigQuery dataset. Supports pagination. | Name | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------------------- | | `dataset_id` | string | Yes | The ID of the dataset to list tables from | | `max_results` | integer | No | Maximum number of tables to return per page | | `page_token` | string | No | Page token from a previous response to retrieve the next page | ## `bigqueryserviceaccount_run_query` [Section titled “bigqueryserviceaccount\_run\_query”](#bigqueryserviceaccount_run_query) Execute a SQL query synchronously against BigQuery and return results immediately. Best for short-running queries. | Name | Type | Required | Description | | ---------------- | ------- | -------- | ------------------------------------------------------------------------------------ | | `create_session` | boolean | No | If true, creates a new session and returns a session ID in the response | | `dry_run` | boolean | No | If true, validates the query and returns estimated bytes processed without executing | | `location` | string | No | Geographic location of the dataset, e.g. US or EU | | `max_results` | integer | No | Maximum number of rows to return in the response | | `query` | string | Yes | SQL query to execute | | `timeout_ms` | integer | No | Maximum milliseconds to wait for query completion before returning | | `use_legacy_sql` | boolean | No | Use BigQuery legacy SQL syntax instead of standard SQL |
---
# DOCUMENT BOUNDARY
---
# Box
> Connect to Box to manage files, folders, users, tasks, webhooks, collaborations, and more using OAuth 2.0.
Connect to Box to manage files, folders, users, groups, collaborations, tasks, comments, webhooks, search, and more using the Box REST API.  Supports authentication: OAuth 2.0  ## Set up the agent connector [Section titled “Set up the agent connector”](#set-up-the-agent-connector) Connect Box to Scalekit so your agent can manage files, folders, users, tasks, and more on behalf of your users. Box uses OAuth 2.0 — users authorize access through Box’s login flow, and Scalekit handles token storage and refresh automatically. You will need: * A Box developer account (free at [developer.box.com](https://developer.box.com)) * Your Box OAuth app’s Client ID and Client Secret * The redirect URI from Scalekit to paste into Box 1. ### Create a Box OAuth app * Go to the [Box Developer Console](https://app.box.com/developers/console) and click **Create New App**. * Select **Custom App** as the app type. * Under authentication method, choose **User Authentication (OAuth 2.0)**. This lets your agent act on behalf of each user who authorizes access. * Enter an app name (e.g. “My Agent App”) and click **Create App**.  2. ### Copy the redirect URI from Scalekit * In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** > **Create Connection**. * Find **Box** and click **Create**. * Click **Use your own credentials** and copy the redirect URI. It looks like: `https://.scalekit.cloud/sso/v1/oauth//callback`  3. ### Add the redirect URI to Box * In the [Box Developer Console](https://app.box.com/developers/console), open your app and go to the **Configuration** tab. * Under **OAuth 2.0 Redirect URI**, paste the redirect URI from Scalekit and click **Save Changes**.  4. ### Select scopes for your app Still on the **Configuration** tab in Box, scroll down to **Application Scopes** and enable the permissions your agent needs: | Scope | Required for | | ------------------------------ | ---------------------------------------------- | | `root_readonly` | Reading files and folders | | `root_readwrite` | Creating, updating, and deleting files/folders | | `manage_groups` | Creating and managing groups | | `manage_webhook` | Creating and managing webhooks | | `manage_managed_users` | Creating and managing enterprise users | | `manage_enterprise_properties` | Accessing enterprise events | Click **Save Changes** after selecting scopes. 5. ### Add credentials in Scalekit * In the [Box Developer Console](https://app.box.com/developers/console), open your app → **Configuration** tab. * Copy your **Client ID** and **Client Secret**. * In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections**, open the Box connection you created, and enter: * **Client ID** — from Box * **Client Secret** — from Box * **Scopes** — select the same scopes you enabled in Box (e.g. `root_readonly`, `root_readwrite`)  * Click **Save**. 6. ### Add a connected account for each user Each user who authorizes Box access becomes a connected account. During authorization, Box will show your app name and request the scopes you configured. **Via dashboard (for testing)** * In [Scalekit dashboard](https://app.scalekit.com), go to your Box connection → **Connected Accounts** → **Add Account**. * Enter a **User ID** (your internal identifier for this user, e.g. `user_123`). * Click **Add** — you will be redirected to Box’s OAuth consent screen to authorize.  **Via API (for production)** In production, generate an authorization link and redirect your user to it: * Node.js ```typescript 1 const { link } = await scalekit.actions.getAuthorizationLink({ 2 connectionName: 'box', 3 identifier: 'user_123', 4 }); 5 // Redirect your user to `link` ``` * Python ```python 1 link_response = scalekit_client.actions.get_authorization_link( 2 connection_name="box", 3 identifier="user_123", 4 ) 5 # Redirect your user to link_response.link ``` After the user authorizes, Scalekit stores their tokens. Your agent can then call Box tools on their behalf without any further redirects. ## Usage [Section titled “Usage”](#usage) ## Getting resource IDs [Section titled “Getting resource IDs”](#getting-resource-ids) Most Box tools require an ID for the resource they operate on. Here is where to find each ID: | Resource | Tool to get ID | Response field | | ------------------- | ------------------------------------------------------------------ | -------------------------------------------------------- | | File ID | `box_folder_items_list` (folder\_id: `"0"`) | `entries[].id` where `entries[].type == "file"` | | Folder ID | `box_folder_items_list` (folder\_id: `"0"`) | `entries[].id` where `entries[].type == "folder"` | | Task ID | `box_file_tasks_list` or `box_task_create` response | `id` | | Task assignment ID | `box_task_assignments_list` | `entries[].id` | | Comment ID | `box_file_comments_list` | `entries[].id` | | Collaboration ID | `box_folder_collaborations_list` or `box_file_collaborations_list` | `entries[].id` | | Collection ID | `box_collections_list` | `entries[].id` (Favorites collection = type `favorites`) | | Webhook ID | `box_webhooks_list` | `entries[].id` | | User ID | `box_user_me_get` (authenticated user) or `box_users_list` | `id` | | Group ID | `box_groups_list` | `entries[].id` | | Group membership ID | `box_group_members_list` or `box_user_memberships_list` | `entries[].id` | | Web link ID | `box_folder_items_list` | `entries[].id` where `entries[].type == "web_link"` | Collaboration ID vs User ID The `collaboration_id` is different from the collaborating user’s ID. After creating a collaboration with `box_collaboration_create`, fetch the collaboration ID using `box_folder_collaborations_list` or `box_file_collaborations_list`. ## Required scopes [Section titled “Required scopes”](#required-scopes) Enable the corresponding Box app scopes before calling tools that need them: | Tools | Required scope | | ------------------------------------------------------------------------- | ------------------------------ | | All file/folder read tools, `box_file_representations_get` | `root_readonly` | | File/folder create, update, delete | `root_readwrite` | | `box_group_*`, `box_user_memberships_list` | `manage_groups` | | `box_webhook_*`, `box_webhooks_list` | `manage_webhook` | | `box_user_create`, `box_user_delete`, `box_users_list`, `box_user_update` | `manage_managed_users` | | `box_events_list` (enterprise stream) | `manage_enterprise_properties` | ## Tool list [Section titled “Tool list”](#tool-list) ### Files [Section titled “Files”](#files) ## `box_file_get` [Section titled “box\_file\_get”](#box_file_get) Retrieves detailed information about a file. | Name | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------------------ | | `file_id` | string | Yes | ID of the file. Get it from `box_folder_items_list` on folder\_id `"0"`. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_file_update` [Section titled “box\_file\_update”](#box_file_update) Updates a file’s name, description, tags, or moves it to another folder. | Name | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------- | | `file_id` | string | Yes | ID of the file to update. | | `name` | string | No | New name for the file. | | `description` | string | No | New description for the file. | | `parent_id` | string | No | ID of the folder to move the file into. | | `tags` | string | No | Comma-separated list of tags. | ## `box_file_delete` [Section titled “box\_file\_delete”](#box_file_delete) Moves a file to the trash. | Name | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | `file_id` | string | Yes | ID of the file to delete. | ## `box_file_copy` [Section titled “box\_file\_copy”](#box_file_copy) Creates a copy of a file in a specified folder. | Name | Type | Required | Description | | ----------- | ------ | -------- | ---------------------------------------- | | `file_id` | string | Yes | ID of the file to copy. | | `parent_id` | string | Yes | ID of the destination folder. | | `name` | string | No | New name for the copied file (optional). | ## `box_file_versions_list` [Section titled “box\_file\_versions\_list”](#box_file_versions_list) Retrieves all previous versions of a file. | Name | Type | Required | Description | | --------- | ------ | -------- | --------------- | | `file_id` | string | Yes | ID of the file. | ## `box_file_thumbnail_get` [Section titled “box\_file\_thumbnail\_get”](#box_file_thumbnail_get) Retrieves a thumbnail image for a file. | Name | Type | Required | Description | | ------------ | ------- | -------- | ------------------------------------------ | | `file_id` | string | Yes | ID of the file. | | `extension` | string | Yes | Thumbnail format: `jpg` or `png`. | | `min_width` | integer | No | Minimum width of the thumbnail in pixels. | | `min_height` | integer | No | Minimum height of the thumbnail in pixels. | ## `box_file_representations_get` [Section titled “box\_file\_representations\_get”](#box_file_representations_get) Retrieves available representations for a file, such as PDFs, extracted text, or image thumbnails. Box generates representations on demand — poll until the `status` is `success` before downloading. | Name | Type | Required | Description | | ------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------- | | `file_id` | string | Yes | ID of the file. Get it from `box_folder_items_list`. | | `x_rep_hints` | string | Yes | Representation formats to request, e.g. `[pdf][extracted_text]` or `[jpg?dimensions=320x320]`. Multiple formats can be combined. | ### Folders [Section titled “Folders”](#folders) ## `box_folder_get` [Section titled “box\_folder\_get”](#box_folder_get) Retrieves a folder’s details and its immediate items. | Name | Type | Required | Description | | ----------- | ------- | -------- | ------------------------------------------------ | | `folder_id` | string | Yes | ID of the folder. Use `"0"` for the root folder. | | `fields` | string | No | Comma-separated list of fields to return. | | `sort` | string | No | Sort order: `id`, `name`, `date`, or `size`. | | `direction` | string | No | Sort direction: `ASC` or `DESC`. | | `offset` | integer | No | Pagination offset. | | `limit` | integer | No | Max items to return (max 1000). | ## `box_folder_items_list` [Section titled “box\_folder\_items\_list”](#box_folder_items_list) Retrieves a paginated list of items in a folder. Use folder\_id `"0"` to start from the root. | Name | Type | Required | Description | | ----------- | ------- | -------- | ------------------------------------------------ | | `folder_id` | string | Yes | ID of the folder. Use `"0"` for the root folder. | | `fields` | string | No | Comma-separated list of fields to return. | | `sort` | string | No | Sort field: `id`, `name`, `date`, or `size`. | | `direction` | string | No | `ASC` or `DESC`. | | `offset` | integer | No | Pagination offset. | | `limit` | integer | No | Max items to return (max 1000). | ## `box_folder_create` [Section titled “box\_folder\_create”](#box_folder_create) Creates a new folder inside a parent folder. | Name | Type | Required | Description | | ----------- | ------ | -------- | -------------------------------------------- | | `name` | string | Yes | Name of the new folder. | | `parent_id` | string | Yes | ID of the parent folder. Use `"0"` for root. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_folder_update` [Section titled “box\_folder\_update”](#box_folder_update) Updates a folder’s name, description, or moves it. | Name | Type | Required | Description | | ------------- | ------ | -------- | ----------------------------------------- | | `folder_id` | string | Yes | ID of the folder to update. | | `name` | string | No | New name for the folder. | | `description` | string | No | New description for the folder. | | `parent_id` | string | No | ID of the new parent folder to move into. | ## `box_folder_delete` [Section titled “box\_folder\_delete”](#box_folder_delete) Moves a folder to the trash. Deleting non-empty folders Pass `recursive: "true"` when deleting a folder that contains files or subfolders. Box rejects the request if the folder has contents and `recursive` is omitted. | Name | Type | Required | Description | | ----------- | ------ | -------- | -------------------------------------------------------------------- | | `folder_id` | string | Yes | ID of the folder to delete. | | `recursive` | string | No | Must be `"true"` to delete folders that contain files or subfolders. | ## `box_folder_copy` [Section titled “box\_folder\_copy”](#box_folder_copy) Creates a copy of a folder and its contents. | Name | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------------ | | `folder_id` | string | Yes | ID of the folder to copy. | | `parent_id` | string | Yes | ID of the destination folder. | | `name` | string | No | New name for the copied folder (optional). | ### Search [Section titled “Search”](#search) ## `box_search` [Section titled “box\_search”](#box_search) Searches files, folders, and web links in Box. | Name | Type | Required | Description | | --------------------- | ------- | -------- | ---------------------------------------------------------------------------------------- | | `query` | string | Yes | Search query string. | | `type` | string | No | Filter by type: `file`, `folder`, or `web_link`. | | `ancestor_folder_ids` | string | No | Comma-separated folder IDs to scope the search. | | `content_types` | string | No | Comma-separated content types: `name`, `description`, `tag`, `comments`, `file_content`. | | `file_extensions` | string | No | Comma-separated file extensions to filter (e.g. `pdf,docx`). | | `created_at_range` | string | No | ISO 8601 date range: `2024-01-01T00:00:00Z,2024-12-31T23:59:59Z`. | | `updated_at_range` | string | No | Date range for last updated. | | `owner_user_ids` | string | No | Comma-separated user IDs to filter by owner. | | `scope` | string | No | Search scope: `user_content` or `enterprise_content`. | | `limit` | integer | No | Max results (max 200). | | `offset` | integer | No | Pagination offset. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_recent_items_list` [Section titled “box\_recent\_items\_list”](#box_recent_items_list) Retrieves files and folders the user accessed recently. | Name | Type | Required | Description | | -------- | ------- | -------- | ------------------------------------------- | | `fields` | string | No | Comma-separated list of fields to return. | | `limit` | integer | No | Max results. | | `marker` | string | No | Pagination marker from a previous response. | ### Collaborations [Section titled “Collaborations”](#collaborations) ## `box_collaboration_create` [Section titled “box\_collaboration\_create”](#box_collaboration_create) Grants a user or group access to a file or folder. | Name | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------ | | `item_id` | string | Yes | ID of the file or folder. | | `item_type` | string | Yes | Type of item: `file` or `folder`. | | `accessible_by_id` | string | Yes | Box user or group ID to grant access to. Get user IDs from `box_users_list`. | | `accessible_by_type` | string | Yes | Type: `user` or `group`. | | `role` | string | Yes | Collaboration role: `viewer`, `previewer`, `uploader`, `previewer_uploader`, `viewer_uploader`, `co-owner`, or `editor`. | | `notify` | string | No | Notify collaborator via email (`true`/`false`). | | `can_view_path` | string | No | Allow user to see path to item (`true`/`false`). | | `expires_at` | string | No | Expiry date in ISO 8601 format. | ## `box_collaboration_get` [Section titled “box\_collaboration\_get”](#box_collaboration_get) Retrieves details of a specific collaboration. | Name | Type | Required | Description | | ------------------ | ------ | -------- | ------------------------------------------------------------------------------------------------------ | | `collaboration_id` | string | Yes | ID of the collaboration. Get it from `box_folder_collaborations_list` — this is **not** the user’s ID. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_collaboration_update` [Section titled “box\_collaboration\_update”](#box_collaboration_update) Updates the role or status of a collaboration. | Name | Type | Required | Description | | ------------------ | ------- | -------- | ---------------------------------------------------------------------- | | `collaboration_id` | string | Yes | ID of the collaboration. Get it from `box_folder_collaborations_list`. | | `role` | string | No | New collaboration role. | | `status` | string | No | Collaboration status: `accepted` or `rejected`. | | `expires_at` | string | No | New expiry date in ISO 8601 format. | | `can_view_path` | boolean | No | Allow user to see path to item. | ## `box_collaboration_delete` [Section titled “box\_collaboration\_delete”](#box_collaboration_delete) Removes a collaboration, revoking user or group access. | Name | Type | Required | Description | | ------------------ | ------ | -------- | -------------------------------------------------------------------------------- | | `collaboration_id` | string | Yes | ID of the collaboration to delete. Get it from `box_folder_collaborations_list`. | ## `box_file_collaborations_list` [Section titled “box\_file\_collaborations\_list”](#box_file_collaborations_list) Retrieves all collaborations on a file. | Name | Type | Required | Description | | --------- | ------ | -------- | ----------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_folder_collaborations_list` [Section titled “box\_folder\_collaborations\_list”](#box_folder_collaborations_list) Retrieves all collaborations on a folder. | Name | Type | Required | Description | | ----------- | ------ | -------- | ----------------------------------------- | | `folder_id` | string | Yes | ID of the folder. | | `fields` | string | No | Comma-separated list of fields to return. | ### Comments [Section titled “Comments”](#comments) ## `box_comment_create` [Section titled “box\_comment\_create”](#box_comment_create) Adds a comment to a file. | Name | Type | Required | Description | | ---------------- | ------ | -------- | -------------------------------------------------- | | `item_id` | string | Yes | ID of the file to comment on. | | `item_type` | string | Yes | Type of item: `file` or `comment` (for replies). | | `message` | string | Yes | Text of the comment. | | `tagged_message` | string | No | Comment text with `@[user_id:user_name]` mentions. | ## `box_comment_get` [Section titled “box\_comment\_get”](#box_comment_get) Retrieves a comment. | Name | Type | Required | Description | | ------------ | ------ | -------- | -------------------------------------------------------- | | `comment_id` | string | Yes | ID of the comment. Get it from `box_file_comments_list`. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_comment_update` [Section titled “box\_comment\_update”](#box_comment_update) Updates the text of a comment. | Name | Type | Required | Description | | ------------ | ------ | -------- | ---------------------------- | | `comment_id` | string | Yes | ID of the comment to update. | | `message` | string | Yes | New text for the comment. | ## `box_comment_delete` [Section titled “box\_comment\_delete”](#box_comment_delete) Removes a comment. | Name | Type | Required | Description | | ------------ | ------ | -------- | ---------------------------- | | `comment_id` | string | Yes | ID of the comment to delete. | ## `box_file_comments_list` [Section titled “box\_file\_comments\_list”](#box_file_comments_list) Retrieves all comments on a file. | Name | Type | Required | Description | | --------- | ------ | -------- | ----------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `fields` | string | No | Comma-separated list of fields to return. | ### Tasks [Section titled “Tasks”](#tasks) ## `box_task_create` [Section titled “box\_task\_create”](#box_task_create) Creates a task on a file. | Name | Type | Required | Description | | ----------------- | ------ | -------- | -------------------------------------------------------------------------- | | `file_id` | string | Yes | ID of the file to attach the task to. Get it from `box_folder_items_list`. | | `message` | string | No | Task message/description. | | `action` | string | No | Action: `review` or `complete`. | | `due_at` | string | No | Due date in ISO 8601 format (e.g. `2025-12-31T00:00:00Z`). | | `completion_rule` | string | No | Completion rule: `all_assignees` or `any_assignee`. | ## `box_task_get` [Section titled “box\_task\_get”](#box_task_get) Retrieves a task’s details. | Name | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------------- | | `task_id` | string | Yes | ID of the task. Get it from `box_file_tasks_list`. | ## `box_task_update` [Section titled “box\_task\_update”](#box_task_update) Updates a task’s message, due date, or completion rule. | Name | Type | Required | Description | | ----------------- | ------ | -------- | ------------------------------------------------------- | | `task_id` | string | Yes | ID of the task to update. | | `message` | string | No | New message for the task. | | `due_at` | string | No | New due date in ISO 8601 format. | | `action` | string | No | New action: `review` or `complete`. | | `completion_rule` | string | No | New completion rule: `all_assignees` or `any_assignee`. | ## `box_task_delete` [Section titled “box\_task\_delete”](#box_task_delete) Removes a task from a file. | Name | Type | Required | Description | | --------- | ------ | -------- | ------------------------- | | `task_id` | string | Yes | ID of the task to delete. | ## `box_file_tasks_list` [Section titled “box\_file\_tasks\_list”](#box_file_tasks_list) Retrieves all tasks associated with a file. | Name | Type | Required | Description | | --------- | ------ | -------- | --------------- | | `file_id` | string | Yes | ID of the file. | ## `box_task_assignment_create` [Section titled “box\_task\_assignment\_create”](#box_task_assignment_create) Assigns a task to a user. | Name | Type | Required | Description | | ------------ | ------ | -------- | ------------------------------------------------------------------- | | `task_id` | string | Yes | ID of the task to assign. Get it from `box_file_tasks_list`. | | `user_id` | string | No | ID of the user to assign the task to. Get it from `box_users_list`. | | `user_login` | string | No | Email login of the user (alternative to `user_id`). | ## `box_task_assignment_get` [Section titled “box\_task\_assignment\_get”](#box_task_assignment_get) Retrieves a specific task assignment. | Name | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------------------------------------- | | `task_assignment_id` | string | Yes | ID of the task assignment. Get it from `box_task_assignments_list`. | ## `box_task_assignment_update` [Section titled “box\_task\_assignment\_update”](#box_task_assignment_update) Updates a task assignment (complete, approve, or reject). | Name | Type | Required | Description | | -------------------- | ------ | -------- | ----------------------------------------------------------------------- | | `task_assignment_id` | string | Yes | ID of the task assignment. | | `message` | string | No | Optional message/comment for the resolution. | | `resolution_state` | string | No | Resolution state: `completed`, `incomplete`, `approved`, or `rejected`. | Completed tasks Box returns a `403` error when you try to delete an assignment on a completed task. This is expected API behavior — only delete assignments on tasks with `incomplete` status. ## `box_task_assignment_delete` [Section titled “box\_task\_assignment\_delete”](#box_task_assignment_delete) Removes a task assignment from a user. | Name | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------ | | `task_assignment_id` | string | Yes | ID of the task assignment to remove. | ## `box_task_assignments_list` [Section titled “box\_task\_assignments\_list”](#box_task_assignments_list) Retrieves all assignments for a task. | Name | Type | Required | Description | | --------- | ------ | -------- | --------------- | | `task_id` | string | Yes | ID of the task. | ### Shared links [Section titled “Shared links”](#shared-links) ## `box_shared_link_file_create` [Section titled “box\_shared\_link\_file\_create”](#box_shared_link_file_create) Creates or updates a shared link for a file. | Name | Type | Required | Description | | -------------- | ------- | -------- | ---------------------------------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `access` | string | No | Shared link access level: `open`, `company`, or `collaborators`. | | `unshared_at` | string | No | Expiry date in ISO 8601 format. | | `password` | string | No | Password to protect the shared link. | | `can_download` | boolean | No | Allow download (`true`/`false`). | | `can_preview` | boolean | No | Allow preview (`true`/`false`). | ## `box_shared_link_folder_create` [Section titled “box\_shared\_link\_folder\_create”](#box_shared_link_folder_create) Creates or updates a shared link for a folder. | Name | Type | Required | Description | | -------------- | ------- | -------- | ---------------------------------------------------------------- | | `folder_id` | string | Yes | ID of the folder. | | `access` | string | No | Shared link access level: `open`, `company`, or `collaborators`. | | `unshared_at` | string | No | Expiry date in ISO 8601 format. | | `password` | string | No | Password to protect the shared link. | | `can_download` | boolean | No | Allow download (`true`/`false`). | ### Collections [Section titled “Collections”](#collections) ## `box_collections_list` [Section titled “box\_collections\_list”](#box_collections_list) Retrieves all collections for the user (e.g. Favorites). | Name | Type | Required | Description | | -------- | ------- | -------- | ----------------------------------------- | | `fields` | string | No | Comma-separated list of fields to return. | | `offset` | integer | No | Pagination offset. | | `limit` | integer | No | Max results. | ## `box_collection_items_list` [Section titled “box\_collection\_items\_list”](#box_collection_items_list) Retrieves the items in a collection. Use `box_collections_list` first to get the collection ID. | Name | Type | Required | Description | | --------------- | ------- | -------- | --------------------------------------------------------- | | `collection_id` | string | Yes | ID of the collection. Get it from `box_collections_list`. | | `fields` | string | No | Comma-separated list of fields to return. | | `offset` | integer | No | Pagination offset. | | `limit` | integer | No | Max results. | ### Metadata [Section titled “Metadata”](#metadata) ## `box_file_metadata_create` [Section titled “box\_file\_metadata\_create”](#box_file_metadata_create) Applies metadata to a file using a metadata template. Requires an enterprise metadata template. | Name | Type | Required | Description | | -------------- | ------ | -------- | ---------------------------------------------------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `scope` | string | Yes | Template scope: `global` or `enterprise`. | | `template_key` | string | Yes | Key of the metadata template. Get it from `box_metadata_templates_list`. | | `data_json` | string | Yes | JSON string of metadata fields and values, e.g. `"{\"department\": \"Finance\"}"`. | ## `box_file_metadata_get` [Section titled “box\_file\_metadata\_get”](#box_file_metadata_get) Retrieves a specific metadata instance on a file. | Name | Type | Required | Description | | -------------- | ------ | -------- | ----------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `scope` | string | Yes | Template scope: `global` or `enterprise`. | | `template_key` | string | Yes | Key of the metadata template. | ## `box_file_metadata_list` [Section titled “box\_file\_metadata\_list”](#box_file_metadata_list) Retrieves all metadata instances attached to a file. | Name | Type | Required | Description | | --------- | ------ | -------- | --------------- | | `file_id` | string | Yes | ID of the file. | ## `box_file_metadata_delete` [Section titled “box\_file\_metadata\_delete”](#box_file_metadata_delete) Removes a metadata instance from a file. | Name | Type | Required | Description | | -------------- | ------ | -------- | ----------------------------------------- | | `file_id` | string | Yes | ID of the file. | | `scope` | string | Yes | Template scope: `global` or `enterprise`. | | `template_key` | string | Yes | Key of the metadata template. | ## `box_folder_metadata_list` [Section titled “box\_folder\_metadata\_list”](#box_folder_metadata_list) Retrieves all metadata instances on a folder. | Name | Type | Required | Description | | ----------- | ------ | -------- | ----------------- | | `folder_id` | string | Yes | ID of the folder. | ## `box_metadata_template_get` [Section titled “box\_metadata\_template\_get”](#box_metadata_template_get) Retrieves a metadata template schema. Returns `404` if no enterprise templates exist. | Name | Type | Required | Description | | -------------- | ------ | -------- | ------------------------------------------------ | | `scope` | string | Yes | Scope of the template: `global` or `enterprise`. | | `template_key` | string | Yes | Key of the metadata template. | ## `box_metadata_templates_list` [Section titled “box\_metadata\_templates\_list”](#box_metadata_templates_list) Retrieves all metadata templates for the enterprise. | Name | Type | Required | Description | | -------- | ------- | -------- | ------------------ | | `marker` | string | No | Pagination marker. | | `limit` | integer | No | Max results. | ### Web links [Section titled “Web links”](#web-links) ## `box_web_link_create` [Section titled “box\_web\_link\_create”](#box_web_link_create) Creates a web link (bookmark) inside a folder. | Name | Type | Required | Description | | ------------- | ------ | -------- | -------------------------------------------- | | `url` | string | Yes | URL of the web link. | | `parent_id` | string | Yes | ID of the parent folder. Use `"0"` for root. | | `name` | string | No | Name for the web link. | | `description` | string | No | Description of the web link. | ## `box_web_link_get` [Section titled “box\_web\_link\_get”](#box_web_link_get) Retrieves a web link’s details. | Name | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------------------------------------------- | | `web_link_id` | string | Yes | ID of the web link. Get it from `box_folder_items_list` (type: `web_link`). | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_web_link_update` [Section titled “box\_web\_link\_update”](#box_web_link_update) Updates a web link’s URL, name, or description. | Name | Type | Required | Description | | ------------- | ------ | -------- | ----------------------------- | | `web_link_id` | string | Yes | ID of the web link to update. | | `url` | string | No | New URL. | | `name` | string | No | New name. | | `description` | string | No | New description. | | `parent_id` | string | No | New parent folder ID. | ## `box_web_link_delete` [Section titled “box\_web\_link\_delete”](#box_web_link_delete) Removes a web link. | Name | Type | Required | Description | | ------------- | ------ | -------- | ----------------------------- | | `web_link_id` | string | Yes | ID of the web link to delete. | ### Trash [Section titled “Trash”](#trash) ## `box_trash_list` [Section titled “box\_trash\_list”](#box_trash_list) Retrieves items in the user’s trash. | Name | Type | Required | Description | | ----------- | ------- | -------- | ----------------------------------------- | | `fields` | string | No | Comma-separated list of fields to return. | | `limit` | integer | No | Max results. | | `offset` | integer | No | Pagination offset. | | `sort` | string | No | Sort field: `name`, `date`, or `size`. | | `direction` | string | No | Sort direction: `ASC` or `DESC`. | ## `box_trash_file_restore` [Section titled “box\_trash\_file\_restore”](#box_trash_file_restore) Restores a file from the trash. | Name | Type | Required | Description | | ----------- | ------ | -------- | --------------------------------------------------------- | | `file_id` | string | Yes | ID of the trashed file. | | `name` | string | No | New name if the original name is already taken. | | `parent_id` | string | No | Parent folder ID if the original location is unavailable. | ## `box_trash_file_permanently_delete` [Section titled “box\_trash\_file\_permanently\_delete”](#box_trash_file_permanently_delete) Permanently deletes a trashed file. This action cannot be undone. | Name | Type | Required | Description | | --------- | ------ | -------- | ----------------------- | | `file_id` | string | Yes | ID of the trashed file. | ## `box_trash_folder_restore` [Section titled “box\_trash\_folder\_restore”](#box_trash_folder_restore) Restores a folder from the trash. | Name | Type | Required | Description | | ----------- | ------ | -------- | ---------------------------------------------------- | | `folder_id` | string | Yes | ID of the trashed folder. | | `name` | string | No | New name if the original is already taken. | | `parent_id` | string | No | New parent folder ID if the original is unavailable. | ## `box_trash_folder_permanently_delete` [Section titled “box\_trash\_folder\_permanently\_delete”](#box_trash_folder_permanently_delete) Permanently deletes a trashed folder. This action cannot be undone. | Name | Type | Required | Description | | ----------- | ------ | -------- | ------------------------- | | `folder_id` | string | Yes | ID of the trashed folder. | ### Webhooks [Section titled “Webhooks”](#webhooks) Webhooks require the `manage_webhook` scope. ## `box_webhook_create` [Section titled “box\_webhook\_create”](#box_webhook_create) Creates a webhook to receive event notifications when something changes in a file or folder. | Name | Type | Required | Description | | ------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `target_id` | string | Yes | ID of the file or folder to watch. | | `target_type` | string | Yes | Type of target: `file` or `folder`. | | `address` | string | Yes | HTTPS URL to receive webhook notifications. Must be publicly accessible. | | `triggers` | array | Yes | Array of event strings, e.g. `["FILE.UPLOADED","FILE.DELETED"]`. See [Box webhook triggers](https://developer.box.com/reference/resources/webhook/) for the full list. | ## `box_webhook_get` [Section titled “box\_webhook\_get”](#box_webhook_get) Retrieves a webhook’s details. | Name | Type | Required | Description | | ------------ | ------ | -------- | --------------------------------------------------- | | `webhook_id` | string | Yes | ID of the webhook. Get it from `box_webhooks_list`. | ## `box_webhook_update` [Section titled “box\_webhook\_update”](#box_webhook_update) Updates a webhook’s address or triggers. | Name | Type | Required | Description | | ------------- | ------ | -------- | ------------------------------------ | | `webhook_id` | string | Yes | ID of the webhook to update. | | `address` | string | No | New HTTPS URL for notifications. | | `triggers` | array | No | New array of event strings. | | `target_id` | string | No | New target ID. | | `target_type` | string | No | New target type: `file` or `folder`. | ## `box_webhook_delete` [Section titled “box\_webhook\_delete”](#box_webhook_delete) Removes a webhook. | Name | Type | Required | Description | | ------------ | ------ | -------- | ---------------------------- | | `webhook_id` | string | Yes | ID of the webhook to delete. | ## `box_webhooks_list` [Section titled “box\_webhooks\_list”](#box_webhooks_list) Retrieves all webhooks for the application. | Name | Type | Required | Description | | -------- | ------- | -------- | ------------------ | | `marker` | string | No | Pagination marker. | | `limit` | integer | No | Max results. | ### Users [Section titled “Users”](#users) User management tools require the `manage_managed_users` scope. Users created with Box must use an email address within the enterprise’s verified domain. ## `box_user_me_get` [Section titled “box\_user\_me\_get”](#box_user_me_get) Retrieves information about the currently authenticated user. No parameters required — use this to get your own user ID. | Name | Type | Required | Description | | -------- | ------ | -------- | ----------------------------------------- | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_user_get` [Section titled “box\_user\_get”](#box_user_get) Retrieves information about a specific user. | Name | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------------ | | `user_id` | string | Yes | ID of the user. Get it from `box_users_list` or `box_user_me_get`. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_users_list` [Section titled “box\_users\_list”](#box_users_list) Retrieves all users in the enterprise. | Name | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------ | | `filter_term` | string | No | Filter users by name or login. | | `user_type` | string | No | Filter by type: `all`, `managed`, or `external`. | | `fields` | string | No | Comma-separated list of fields to return. | | `limit` | integer | No | Max users to return. | | `offset` | integer | No | Pagination offset. | ## `box_user_create` [Section titled “box\_user\_create”](#box_user_create) Creates a new managed user in the enterprise. | Name | Type | Required | Description | | ------------------------- | ------- | -------- | ------------------------------------------------------------------------------ | | `name` | string | Yes | Full name of the user. | | `login` | string | No | Email address (login) for managed users. Must be within the enterprise domain. | | `role` | string | No | User role: `user` or `coadmin`. | | `space_amount` | integer | No | Storage quota in bytes (`-1` for unlimited). | | `is_platform_access_only` | boolean | No | Set `true` for app users (no login required). | ## `box_user_update` [Section titled “box\_user\_update”](#box_user_update) Updates a user’s properties in the enterprise. | Name | Type | Required | Description | | ---------------- | ------- | -------- | ---------------------------------------------------------- | | `user_id` | string | Yes | ID of the user to update. | | `name` | string | No | New full name. | | `role` | string | No | New role: `user` or `coadmin`. | | `status` | string | No | New status: `active`, `inactive`, or `cannot_delete_edit`. | | `space_amount` | integer | No | Storage quota in bytes. | | `tracking_codes` | string | No | Tracking codes as a JSON array string. | ## `box_user_delete` [Section titled “box\_user\_delete”](#box_user_delete) Removes a user from the enterprise. | Name | Type | Required | Description | | --------- | ------ | -------- | ---------------------------------------------------------- | | `user_id` | string | Yes | ID of the user to delete. | | `notify` | string | No | Notify user via email (`true`/`false`). | | `force` | string | No | Force deletion even if user owns content (`true`/`false`). | ## `box_user_memberships_list` [Section titled “box\_user\_memberships\_list”](#box_user_memberships_list) Retrieves all group memberships for a user. | Name | Type | Required | Description | | --------- | ------- | -------- | ------------------ | | `user_id` | string | Yes | ID of the user. | | `limit` | integer | No | Max results. | | `offset` | integer | No | Pagination offset. | ### Groups [Section titled “Groups”](#groups) Group tools require the `manage_groups` scope. ## `box_groups_list` [Section titled “box\_groups\_list”](#box_groups_list) Retrieves all groups in the enterprise. | Name | Type | Required | Description | | ------------- | ------- | -------- | ----------------------------------------- | | `filter_term` | string | No | Filter groups by name. | | `fields` | string | No | Comma-separated list of fields to return. | | `limit` | integer | No | Max results. | | `offset` | integer | No | Pagination offset. | ## `box_group_create` [Section titled “box\_group\_create”](#box_group_create) Creates a new group in the enterprise. | Name | Type | Required | Description | | -------------------------- | ------ | -------- | ---------------------------------------------------------------------------------------- | | `name` | string | Yes | Name of the group. | | `description` | string | No | Description of the group. | | `provenance` | string | No | Identifier to distinguish manually created vs synced groups. | | `invitability_level` | string | No | Who can invite to group: `admins_only`, `admins_and_members`, or `all_managed_users`. | | `member_viewability_level` | string | No | Who can view group members: `admins_only`, `admins_and_members`, or `all_managed_users`. | ## `box_group_get` [Section titled “box\_group\_get”](#box_group_get) Retrieves information about a group. | Name | Type | Required | Description | | ---------- | ------ | -------- | ----------------------------------------------- | | `group_id` | string | Yes | ID of the group. Get it from `box_groups_list`. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_group_update` [Section titled “box\_group\_update”](#box_group_update) Updates a group’s properties. | Name | Type | Required | Description | | -------------------------- | ------ | -------- | ---------------------------------------------------------------------------- | | `group_id` | string | Yes | ID of the group to update. | | `name` | string | No | New name for the group. | | `description` | string | No | New description. | | `invitability_level` | string | No | Who can invite: `admins_only`, `admins_and_members`, or `all_managed_users`. | | `member_viewability_level` | string | No | Who can view members. | ## `box_group_delete` [Section titled “box\_group\_delete”](#box_group_delete) Permanently deletes a group. | Name | Type | Required | Description | | ---------- | ------ | -------- | -------------------------- | | `group_id` | string | Yes | ID of the group to delete. | ## `box_group_members_list` [Section titled “box\_group\_members\_list”](#box_group_members_list) Retrieves all members of a group. | Name | Type | Required | Description | | ---------- | ------- | -------- | ------------------ | | `group_id` | string | Yes | ID of the group. | | `limit` | integer | No | Max results. | | `offset` | integer | No | Pagination offset. | ## `box_group_membership_add` [Section titled “box\_group\_membership\_add”](#box_group_membership_add) Adds a user to a group. | Name | Type | Required | Description | | ---------- | ------ | -------- | ---------------------------------------------------- | | `user_id` | string | Yes | ID of the user to add. Get it from `box_users_list`. | | `group_id` | string | Yes | ID of the group. | | `role` | string | No | Role in the group: `member` or `admin`. | ## `box_group_membership_get` [Section titled “box\_group\_membership\_get”](#box_group_membership_get) Retrieves a specific group membership. | Name | Type | Required | Description | | --------------------- | ------ | -------- | ----------------------------------------------------------------- | | `group_membership_id` | string | Yes | ID of the group membership. Get it from `box_group_members_list`. | | `fields` | string | No | Comma-separated list of fields to return. | ## `box_group_membership_update` [Section titled “box\_group\_membership\_update”](#box_group_membership_update) Updates a user’s role in a group. | Name | Type | Required | Description | | --------------------- | ------ | -------- | ------------------------------- | | `group_membership_id` | string | Yes | ID of the membership to update. | | `role` | string | No | New role: `member` or `admin`. | ## `box_group_membership_remove` [Section titled “box\_group\_membership\_remove”](#box_group_membership_remove) Removes a user from a group. | Name | Type | Required | Description | | --------------------- | ------ | -------- | --------------------------------------------------------------------------- | | `group_membership_id` | string | Yes | ID of the group membership to remove. Get it from `box_group_members_list`. | ### Events [Section titled “Events”](#events) ## `box_events_list` [Section titled “box\_events\_list”](#box_events_list) Retrieves events from the Box event stream. Use `admin_logs` for enterprise-wide events (requires `manage_enterprise_properties` scope). | Name | Type | Required | Description | | ----------------- | ------- | -------- | ------------------------------------------------------------- | | `stream_type` | string | No | Event stream type: `all`, `changes`, `sync`, or `admin_logs`. | | `stream_position` | string | No | Pagination position from a previous response. | | `limit` | integer | No | Max events to return. | | `event_type` | string | No | Comma-separated list of event types to filter. | | `created_after` | string | No | Return events after this date (ISO 8601). | | `created_before` | string | No | Return events before this date (ISO 8601). |
---
# DOCUMENT BOUNDARY
---
# Glossary
> A comprehensive glossary of terms related to authentication, authorization, and identity management in B2B SaaS applications.
## Access Token [Section titled “Access Token”](#access-token) * **Definition**: A credential (often a JWT) issued by the authorization server that the client uses to access the resource server. It represents the client’s authorization and typically has an expiry time and scopes attached. The resource server validates this token. ## Administrator [Section titled “Administrator”](#administrator) * **Definition**: An IT administrator responsible for managing identity provider configurations within a customer organization. ## Admin Portal [Section titled “Admin Portal”](#admin-portal) * **Definition**: A customizable web interface for customers’ IT administrators to manage identity provider configurations. ## AI Agent Identity and Attestation [Section titled “AI Agent Identity and Attestation”](#ai-agent-identity-and-attestation) * **Definition**: A process by which an AI agent proves its identity to an authorization server, often using cryptographic evidence (e.g. signed JWT assertions or hardware-backed keys), so the server can trust requests coming from that agent. ## API Endpoint [Section titled “API Endpoint”](#api-endpoint) * **Definition**: A specific URL where an API can be accessed to perform specific operations or retrieve data. ## API Key [Section titled “API Key”](#api-key) * **Definition**: A unique identifier used to authenticate API requests to Scalekit, allowing secure access to the platform’s features and services. ## App [Section titled “App”](#app) * **Definition**: Another term for an application, representing the software product or service sold to customers. ## Application [Section titled “Application”](#application) * **Definition**: The software product or service offered by B2B App developers to customers. * **Example**: A workspace can contain multiple applications. ## Audit Log [Section titled “Audit Log”](#audit-log) * **Definition**: A record of all activities and changes made within the B2B App, used for security and compliance purposes. ## Authentication [Section titled “Authentication”](#authentication) * **Definition**: The process of verifying the identity of a user or system attempting to access the B2B App. ## Authorization [Section titled “Authorization”](#authorization) * **Definition**: The process of determining what actions or resources a user is allowed to access within the B2B App. ## Authorization Server [Section titled “Authorization Server”](#authorization-server) * **Definition**: The server in OAuth that authenticates clients and issues tokens (could be a part of your SaaS or a third-party IdP like Okta Azure AD, etc.). It essentially says “Yes, client X, here is a token proving you are authenticated and allowed to do Y.” ## Authorization URL [Section titled “Authorization URL”](#authorization-url) * **Definition**: The URL to which users are redirected to grant authorization for the B2B App. ## B2B App [Section titled “B2B App”](#b2b-app) * **Definition**: An application designed for use by other businesses or organizations to streamline operations. ## B2B SaaS App [Section titled “B2B SaaS App”](#b2b-saas-app) * **Definition**: A type of B2B App delivered over the internet, allowing access without local installation. ## Claims [Section titled “Claims”](#claims) * **Definition**: Information about a user that is passed from an identity provider to a service provider during authentication. ## Client Credentials Flow [Section titled “Client Credentials Flow”](#client-credentials-flow) * **Definition**: The OAuth process where a machine client exchanges its client ID and secret for an access token from the auth server. No user involved. The resulting token represents the machine and carries scopes for what it can do. ## Configuration [Section titled “Configuration”](#configuration) * **Definition**: The settings and parameters that define how the B2B App interacts with Scalekit and other services. ## Connection [Section titled “Connection”](#connection) * **Definition**: A link between the B2B App and a customer’s identity provider for enabling Single Sign-On (SSO). * **Example**: Each organization can have its own unique connection. ## Customer [Section titled “Customer”](#customer) * **Definition**: A business or organization that uses the application to meet specific needs. ## Custom Attribute [Section titled “Custom Attribute”](#custom-attribute) * **Definition**: Additional fields added to user data in Scalekit for storing extra information. ## Dashboard [Section titled “Dashboard”](#dashboard) * **Definition**: The main control panel within Scalekit for configuring settings, viewing analytics, and managing integrations. ## Deprovisioning [Section titled “Deprovisioning”](#deprovisioning) * **Definition**: The process of removing user access and accounts when they are no longer needed or authorized. ## Directory Provider [Section titled “Directory Provider”](#directory-provider) * **Definition**: An organization offering directory services, including identity providers. ## Directory Sync [Section titled “Directory Sync”](#directory-sync) * **Definition**: A module in Scalekit for automatic provisioning and deprovisioning of user accounts. ## Documentation [Section titled “Documentation”](#documentation) * **Definition**: Comprehensive guides and references that explain how to use and integrate with Scalekit’s features and services. ## Dynamic Client Registration [Section titled “Dynamic Client Registration”](#dynamic-client-registration) * **Definition**: A protocol (RFC 7591) that allows a client application to programmatically register itself with an authorization server to obtain credentials (client ID/secret, etc.). Useful for large-scale or third-party ecosystems where manual registration of clients is not feasible or to enable self-service integration in a controlled way. ## Environment [Section titled “Environment”](#environment) * **Definition**: Different versions or instances of an application, such as test and live environments. * **Example**: Each environment has its own settings and is isolated for security. ## Error Handling [Section titled “Error Handling”](#error-handling) * **Definition**: The process of managing and responding to errors that occur during API calls or application operations. ## Federation [Section titled “Federation”](#federation) * **Definition**: The process of establishing trust between different identity providers and service providers for seamless authentication. ## ID Token [Section titled “ID Token”](#id-token) * **Definition**: A JSON Web Token (JWT) issued by the identity provider containing user identity information. ## Identity Provider (IdP) [Section titled “Identity Provider (IdP)”](#identity-provider-idp) * **Definition**: A service that verifies user identity and provides information about user attributes. ## IdP Simulator [Section titled “IdP Simulator”](#idp-simulator) * **Definition**: A tool that mimics the behavior of an identity provider for testing integrations. ## Integration [Section titled “Integration”](#integration) * **Definition**: The process of connecting Scalekit with other systems or services to enable seamless data flow and functionality. ## JWT [Section titled “JWT”](#jwt) * **Definition**: A standard format for representing claims securely between two parties. It is a compact, URL-safe means of representing claims securely between two parties. ## Logout [Section titled “Logout”](#logout) * **Definition**: The process of ending a user’s session and revoking their access to the B2B App. ## Machine-to-Machine (M2M) Authentication [Section titled “Machine-to-Machine (M2M) Authentication”](#machine-to-machine-m2m-authentication) * **Definition**: Methods for verifying identity between two automated services or software entities without human intervention. Ensures a client program (machine) is trusted by the service it calls, typically via tokens, keys, or certificates. ## MFA (Multi-Factor Authentication) [Section titled “MFA (Multi-Factor Authentication)”](#mfa-multi-factor-authentication) * **Definition**: A security feature that requires users to provide multiple forms of verification before accessing the B2B App. ## Model Context Protocol (MCP) [Section titled “Model Context Protocol (MCP)”](#model-context-protocol-mcp) * **Definition**: A new protocol (spearheaded by Anthropic and others) to standardize how AI models (assistants) can interact with external tools and data. It defines how AI agents can discover available “tools” (APIs) and the context to call them. For auth, MCP leverages OAuth 2.1 – effectively requiring AI agents to go through a secure authorization process to get access to those tools. Think of it as an evolving standard to make AI to SaaS integrations plug-and-play, with security built-in via OAuth. ## Mutual TLS (mTLS) [Section titled “Mutual TLS (mTLS)”](#mutual-tls-mtls) * **Definition**: A transport layer security mechanism where *both client and server present certificates* to mutually authenticate each other during the TLS handshake. Provides strong assurance of identities at connection level and encrypts the traffic. Used in high-security environments and internal service-to-service auth. ## Normalized Payload [Section titled “Normalized Payload”](#normalized-payload) * **Definition**: A standardized format for data sent from Scalekit to the B2B App. ## OAuth [Section titled “OAuth”](#oauth) * **Definition**: A standard protocol for authorization enabling limited access to user data. ## OAuth 2.0/OAuth 2.1 [Section titled “OAuth 2.0/OAuth 2.1”](#oauth-20oauth-21) * **Definition**: An authorization framework widely used for granting access to resources. OAuth 2.0 defines various *flows* (grant types) for different scenarios (authorization code, client credentials, etc.). OAuth 2.1 is an incremental update that compiles security best practices (PKCE required, no legacy flows, etc.). In M2M context, OAuth’s **Client Credentials Grant** is most relevant, allowing a service to get an access token using its own credentials. ## OAuth 2.0 Token Exchange (RFC 8693) [Section titled “OAuth 2.0 Token Exchange (RFC 8693)”](#oauth-20-token-exchange-rfc-8693) * **Definition**: A protocol that lets one token be exchanged for another—for example, an AI agent exchanging its machine-client token for a token scoped to call a downstream service on behalf of a user or another service. Enables delegation and impersonation scenarios. ## OIDC [Section titled “OIDC”](#oidc) * **Definition**: A standard protocol for authentication that builds on OAuth 2.0. ## OpenID Connect (OIDC) [Section titled “OpenID Connect (OIDC)”](#openid-connect-oidc) * **Definition**: An identity layer on top of OAuth 2.0 (often used for user authentication). Mentioned here because the discovery document and id\_token concepts come from OIDC. OIDC isn’t directly about M2M auth (it’s user-centric), but the OIDC discovery (`.well-known`) and JWT usage are leveraged in service auth too. ## Organization [Section titled “Organization”](#organization) * **Definition**: The customers of B2B Apps, typically businesses. * **Example**: Each business is considered an organization with its own users. ## PKCE (Proof Key for Code Exchange) [Section titled “PKCE (Proof Key for Code Exchange)”](#pkce-proof-key-for-code-exchange) * **Definition**: An extension to OAuth used to prevent interception of authorization codes. The client generates a random secret (code verifier) and sends a hashed version (code challenge) in the auth request, then must present the original secret when redeeming the code. Ensures that even if an attacker intercepts the auth code, they can’t exchange it without the secret. PKCE is now recommended for any OAuth client that can’t secure a client secret – including mobile, SPA, and some machine clients. ## PKI (Public Key Infrastructure) [Section titled “PKI (Public Key Infrastructure)”](#pki-public-key-infrastructure) * **Definition**: The system of certificate authorities, processes, and tools for managing digital certificates (like those used in mTLS). Involves issuing certs, distributing them, rotating when expired, revoking if compromised, etc. A robust PKI is needed to effectively use certificate-based auth at scale. ## Provisioning [Section titled “Provisioning”](#provisioning) * **Definition**: The process of creating and managing user accounts and access rights in the B2B App. ## Rate Limiting [Section titled “Rate Limiting”](#rate-limiting) * **Definition**: A mechanism that controls the rate of requests a user or application can make to the API within a specific time period. ## Refresh Token [Section titled “Refresh Token”](#refresh-token) * **Definition**: A long-lived token that can be used to get new access tokens without re-authenticating. In M2M auth, refresh tokens are rarely used because the client can just use its credentials again. Refresh tokens are more for user-based flows to avoid prompting the user frequently. ## Resource Server [Section titled “Resource Server”](#resource-server) * **Definition**: The API or service that the client wants to use – it receives tokens from clients and decides whether to accept them (by validating them). In our context, your SaaS API is a resource server that expects a valid token for requests. ## Role-Based Access Control (RBAC) [Section titled “Role-Based Access Control (RBAC)”](#role-based-access-control-rbac) * **Definition**: A method of regulating access to resources based on the roles of individual users within an organization. ## SAML Assertion [Section titled “SAML Assertion”](#saml-assertion) * **Definition**: A statement by an identity provider indicating a user’s authentication status. ## SCIM [Section titled “SCIM”](#scim) * **Definition**: SCIM (System for Cross-domain Identity Management) is a standard protocol for automating the provisioning and deprovisioning of user accounts and their attributes between an identity provider and a service provider. ## Scopes [Section titled “Scopes”](#scopes) * **Definition**: Strings that define what access is being requested or granted in an OAuth token. For example, `read:inventory` or `payments:create`. Scopes let the token carry permissions, enabling the resource server to allow or deny requests based on scope. Principle of least privilege is implemented by granting minimal scopes. ## Service Account [Section titled “Service Account”](#service-account) * **Definition**: A non-human account used by a software service. In context, it’s an identity set up for a machine to use. For example, a service account could be created for “Data Sync Service” in a customer’s tenant on your app. Service accounts have credentials (like client ID/secret or keys) to authenticate, and usually have roles or scopes assigned just like a user would. They enable organization-level or service-level tokens without tying to an actual person. ## Service Provider [Section titled “Service Provider”](#service-provider) * **Definition**: An entity offering a product or service to another organization or individual, especially in SSO contexts. ## Session [Section titled “Session”](#session) * **Definition**: A period of interaction between a user and the B2B App, typically starting with authentication and ending with logout. ## Social Connection [Section titled “Social Connection”](#social-connection) * **Definition**: Allows users to sign in using their social media accounts. ## SSO (Single Sign-On) [Section titled “SSO (Single Sign-On)”](#sso-single-sign-on) * **Definition**: An authentication method that allows users to access multiple applications with a single set of credentials. ## Team Member [Section titled “Team Member”](#team-member) * **Definition**: Individuals from the B2B App developer’s company who use Scalekit to manage applications. * **Roles**: Can include developers, product managers, or customer support staff. ## Tenant [Section titled “Tenant”](#tenant) * **Definition**: An isolated instance of the B2B App for a specific customer organization, with its own data and configurations. ## Token [Section titled “Token”](#token) * **Definition**: A piece of data that represents a user’s authentication status and permissions, used for accessing protected resources. ## User [Section titled “User”](#user) * **Definition**: An individual who uses the B2B App, typically belonging to a customer organization. ## User Attribute [Section titled “User Attribute”](#user-attribute) * **Definition**: Properties describing a user’s identity, used for authentication and access control. ## Webhook [Section titled “Webhook”](#webhook) * **Definition**: A mechanism for the B2B App to receive notifications or updates from Scalekit. ## Webhook Payload [Section titled “Webhook Payload”](#webhook-payload) * **Definition**: The data sent by Scalekit to the B2B App when a webhook is triggered, containing information about the event. ## Workspace [Section titled “Workspace”](#workspace) * **Definition**: A centralized hub for B2B App developers to manage applications and settings. * **Example**: Think of it as a command center for efficient application management. ## Zero Trust Security [Section titled “Zero Trust Security”](#zero-trust-security) * **Definition**: A security model where no user or device is inherently trusted, even if inside the network. Every access request must be authenticated, authorized, and continuously validated. For M2M, this means authenticating every service communication, minimizing implicit trust, and verifying identities at multiple layers (network & application). It often involves micro-segmentation and strict identity and access management for every machine identity.
---
# DOCUMENT BOUNDARY
---
# Interceptor triggers
> The points in the authentication flow where Scalekit calls your interceptor endpoint
## `PRE_SIGNUP` [Section titled “PRE\_SIGNUP”](#pre_signup) Fires before a user creates a new organization. Use this to validate email domains, check against blocklists, or enforce custom signup policies. ### Request body from Scalekit [Section titled “Request body from Scalekit”](#request-body-from-scalekit) PRE\_SIGNUP — request body ```json 1 { 2 "display_name": "Validate email domain", 3 "trigger_point": "PRE_SIGNUP", 4 "interceptor_context": { 5 "environment_id": "env_92561807201272162", 6 "user_id": "usr_93418238346728951", // Present only if user exists in another organization 7 "user_email": "john.doe@acmecorp.com", // Email attempting to sign up 8 "connection_details": [ 9 { 10 "id": "conn_92561808744978132", 11 "type": "OAUTH", // OAUTH, SAML, OIDC, or PASSWORDLESS 12 "provider": "GOOGLE" // Identity provider used for authentication 13 } 14 ], 15 //Contains parameters from the /oauth/authorize request 16 "auth_request": { 17 "connection_id": "conn_81665025441299343", 18 "organization_id": "org_102953846317318346", 19 "domain": "foocorp.com", 20 "login_hint": "john.doe@example.com", 21 "state": "xsrPHl7k7ARgdhC6" 22 }, 23 "device_type": "Desktop", // Desktop, Mobile, Tablet, or Unknown 24 "ip_address": "203.0.113.24", // Client's IP address for geolocation or blocklist checks 25 "region": "IN", // Two-letter country code 26 "city": "Bengaluru", 27 "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36...", 28 "triggered_at": "2025-10-09T09:48:02.875Z" // ISO 8601 timestamp 29 }, 30 "data": { 31 // User object present only when user already exists in another organization 32 "user": { 33 "id": "usr_93418238346728951", 34 "name": "John Doe", 35 "email": "john.doe@acmecorp.com", 36 "email_verified": true, 37 "created_at": "2025-10-06T11:06:49.120Z", 38 "updated_at": "2025-10-06T13:33:06.479Z", 39 "given_name": "John", 40 "family_name": "Doe", 41 "metadata": { 42 "type": "social_user" 43 }, 44 "memberships": [ // Existing organization memberships 45 { 46 "organization_id": "org_93418204671239864", 47 "status": "ACTIVE", 48 "roles": [ 49 "admin" 50 ], 51 "metadata": { 52 "cost": { 53 "category": "platform", 54 "region": "US" 55 }, 56 "department": "engineering" 57 }, 58 "organization_name": "Example inc" 59 } 60 ] 61 } 62 } 63 } ``` ### Response format to return [Section titled “Response format to return”](#response-format-to-return) PRE\_SIGNUP — response body ```json 1 { 2 // Required: choose ALLOW or DENY 3 "decision": "DENY", // ALLOW | DENY 4 // Optional with DENY 5 "error": { 6 "message": "Only @acmecorp.com email addresses are allowed to sign up" // Shown to user when DENY 7 }, 8 // Optional with ALLOW, Include when the user is to be provisioned in an existing organization. 9 "response": { 10 "create_organization_membership": { 11 // either external_organization_id or organization_id is required 12 "external_organization_id": "ext_B6YycAGRaPmnuxAFPT5KI4HBHxr4qWX", 13 "organization_id": "org_102953846317318346", 14 "roles": [ 15 "admin", 16 "viewer" 17 ] 18 } 19 } 20 } ``` ## `PRE_SESSION_CREATION` [Section titled “PRE\_SESSION\_CREATION”](#pre_session_creation) Fires before session tokens are issued for a user. Use this to add custom claims to tokens, apply conditional access policies, or integrate with external authorization systems. ### Request body from Scalekit [Section titled “Request body from Scalekit”](#request-body-from-scalekit-1) PRE\_SESSION\_CREATION — request body ```json 1 { 2 "display_name": "Add custom claims to tokens", 3 "trigger_point": "PRE_SESSION_CREATION", 4 "interceptor_context": { 5 "environment_id": "env_92561807204567213", 6 "user_id": "usr_93418238346728951", 7 "user_email": "john.doe@acmecorp.com", 8 "organization_id": "org_93418204671239864", // Organization user is logging into 9 "connection_details": [ 10 { 11 "id": "conn_92561808744978132", 12 "type": "OAUTH", // Authentication method used 13 "provider": "GOOGLE" 14 } 15 ], 16 "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36...", 17 "device_type": "Desktop", // Desktop, Mobile, Tablet, or Unknown 18 "ip_address": "203.0.113.24", // Use for conditional access based on location 19 "region": "US", // Two-letter country code 20 "city": "San Francisco", 21 "triggered_at": "2025-10-08T15:22:42.381Z" // ISO 8601 timestamp 22 }, 23 "data": { 24 "user": { 25 "id": "usr_93418238346728951", 26 "name": "John Doe", 27 "email": "john.doe@acmecorp.com", 28 "email_verified": true, 29 "created_at": "2025-10-06T11:06:49.120Z", 30 "updated_at": "2025-10-06T13:33:06.479Z", 31 "first_name": "John", 32 "last_name": "Doe", 33 "memberships": [ // All organizations this user belongs to 34 { 35 "organization_id": "org_93418204671239864", 36 "status": "ACTIVE" 37 } 38 ] 39 } 40 } 41 } ``` ### Response format to return [Section titled “Response format to return”](#response-format-to-return-1) PRE\_SESSION\_CREATION — response body ```json 1 { 2 "decision": "ALLOW", // Required: ALLOW to issue tokens, DENY to block login 3 "response": { 4 "claims": { // Optional: Custom claims added to both access and ID tokens 5 "subscription_tier": "enterprise", 6 "data_region": "us-west-2", 7 "feature_flags": ["analytics_dashboard", "api_access", "custom_branding"], 8 "account_manager": "jane.smith@acmecorp.com" 9 } 10 } 11 } ``` ## `PRE_USER_INVITATION` [Section titled “PRE\_USER\_INVITATION”](#pre_user_invitation) Fires before an invitation is created or sent for a new organization member. Use this to validate invitee email addresses, enforce invitation policies, or check user limits. ### Request body from Scalekit [Section titled “Request body from Scalekit”](#request-body-from-scalekit-2) PRE\_USER\_INVITATION — request body ```json 1 { 2 "display_name": "Validate invitation policy", 3 "trigger_point": "PRE_USER_INVITATION", 4 "interceptor_context": { 5 "environment_id": "env_92561807201272162", 6 "user_id": "usr_93418238346728951", // Present only if invitee already exists in another org 7 "user_email": "sarah.johnson@contractor.com", // Email address being invited 8 "organization_id": "org_93731871904672153", // Organization sending the invitation 9 "city": "Bengaluru", 10 "device_type": "Desktop", // Device of the person sending the invitation 11 "ip_address": "182.156.5.2", // IP of the person sending the invitation 12 "region": "IN", // Two-letter country code 13 "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36...", 14 "triggered_at": "2025-10-09T12:50:41.803Z" // ISO 8601 timestamp 15 }, 16 "data": { 17 "organization": { // Organization details for context 18 "id": "org_93731871904672153", 19 "name": "Acme Corp" 20 } 21 } 22 } ``` ### Response format to return [Section titled “Response format to return”](#response-format-to-return-2) PRE\_USER\_INVITATION — response body ```json 1 { 2 "decision": "DENY", // Required: ALLOW to send invitation, DENY to block 3 "error": { 4 "message": "Cannot invite users from external domains. Please use @acmecorp.com email addresses." // Shown when DENY 5 } 6 } ``` ## `PRE_M2M_TOKEN_CREATION` [Section titled “PRE\_M2M\_TOKEN\_CREATION”](#pre_m2m_token_creation) Fires before issuing a machine-to-machine access token. Use this to add custom claims, modify scopes dynamically, or apply conditional access rules for service-to-service authentication. ### Request body from Scalekit [Section titled “Request body from Scalekit”](#request-body-from-scalekit-3) PRE\_M2M\_TOKEN\_CREATION — request body ```json 1 { 2 "display_name": "Validate M2M client permissions", 3 "trigger_point": "PRE_M2M_TOKEN_CREATION", 4 "interceptor_context": { 5 "environment_id": "env_17002334043308132", 6 "client_id": "m2morg_93710427703245914", // M2M client requesting the token 7 "user_agent": "deployment-service/2.1.0", // Service making the request 8 "device_type": "Unknown", 9 "triggered_at": "2025-10-08T21:22:20.173Z" // ISO 8601 timestamp 10 }, 11 "data": { 12 "m2m_token_claims": { // Claims that will be included in the token 13 "client_id": "m2morg_93710427703245914", 14 "claims": { 15 "custom_claims": { // Existing custom claims from client configuration 16 "service_name": "deployment-automation", 17 "deployment_environment": "production" 18 }, 19 "oid": "org_89669394174574792", // Organization ID for this M2M client 20 "scope": "deploy:applications read:deployments write:logs", // Space-separated scopes 21 "scopes": [ // Array of individual scopes requested 22 "deploy:applications", 23 "read:deployments", 24 "write:logs" 25 ] 26 } 27 } 28 } 29 } ``` ### Response format to return [Section titled “Response format to return”](#response-format-to-return-3) PRE\_M2M\_TOKEN\_CREATION — response body ```json 1 { 2 "decision": "ALLOW", // Required: ALLOW to issue token, DENY to block 3 "response": { 4 "claims": { // Optional: Add or modify claims in the M2M token 5 "scope": "deploy:applications read:deployments", // Can modify scopes dynamically 6 "aud": "https://api.acmecorp.com", // Target audience for the token 7 "rate_limit": "1000", // Custom claim for rate limiting 8 "environment": "production" // Custom claim for environment context 9 } 10 } 11 } ```
---
# DOCUMENT BOUNDARY
---
# Directory events
> Explore the webhook events related to directory operations in Scalekit, including user and group creation, updates, and deletions.
## Directory connection events [Section titled “Directory connection events”](#directory-connection-events) ### `organization.directory_enabled` [Section titled “organization.directory\_enabled”](#organizationdirectory_enabled) This webhook is triggered when a directory sync is enabled. The event type is `organization.directory_enabled` For most SCIM providers, `organization.directory_enabled` is emitted as soon as an admin selects the identity provider in the Scalekit admin portal. Scalekit can begin listening for directory events immediately, so customers often see `organization.directory_created` and `organization.directory_enabled` before the admin finishes configuration on the provider side. Google SCIM is the main exception. Because it requires an additional OAuth authorization step, `organization.directory_enabled` is emitted only after that authorization is completed. This differs from [`organization.sso_enabled`](/reference/webhooks/sso-events/#organizationsso_enabled), which is emitted only after the admin finishes the full SSO configuration. organization.directory\_enabled ```json 1 { 2 "environment_id": "env_27758032200925221", 3 "id": "evt_55136848686613000", 4 "object": "Directory", 5 "occurred_at": "2025-01-15T08:55:22.802860294Z", 6 "organization_id": "org_55135410258444802", 7 "spec_version": "1", 8 "type": "organization.directory_enabled", 9 "data": { 10 "directory_type": "SCIM", 11 "enabled": false, 12 "id": "dir_55135622825771522", 13 "organization_id": "org_55135410258444802", 14 "provider": "OKTA", 15 "updated_at": "2025-01-15T08:55:22.792993454Z" 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------- | ------------------------------------------------------------- | | `id` | string | Unique identifier for the directory connection | | `directory_type` | string | The type of directory synchronization | | `enabled` | boolean | Indicates if the directory sync is enabled | | `environment_id` | string | Identifier for the environment | | `last_sync_at` | null | Timestamp of the last synchronization, null if not yet synced | | `organization_id` | string | Identifier for the organization | | `provider` | string | The provider of the directory | | `updated_at` | string | Timestamp of when the configuration was last updated | | `occurred_at` | string | Timestamp of when the event occurred | ### `organization.directory_disabled` [Section titled “organization.directory\_disabled”](#organizationdirectory_disabled) This webhook is triggered when a directory sync is disabled. The event type is `organization.directory_disabled` organization.directory\_disabled ```json 1 { 2 "spec_version": "1", 3 "id": "evt_53891640779079756", 4 "type": "organization.directory_disabled", 5 "occurred_at": "2025-01-06T18:45:21.057814Z", 6 "environment_id": "env_53814739859406915", 7 "organization_id": "org_53879494091473415", 8 "object": "Directory", 9 "data": { 10 "directory_type": "SCIM", 11 "enabled": false, 12 "id": "dir_53879621145330183", 13 "organization_id": "org_53879494091473415", 14 "provider": "OKTA", 15 "updated_at": "2025-01-06T18:45:21.04978184Z" 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------- | -------------------------------------------------------------------------------- | | `directory_type` | string | Type of directory protocol used for synchronization | | `enabled` | boolean | Indicates whether the directory synchronization is currently enabled or disabled | | `id` | string | Unique identifier for the directory connection | | `last_sync_at` | string | Timestamp of the most recent directory synchronization | | `organization_id` | string | Unique identifier of the organization associated with this directory | | `provider` | string | Identity provider for the directory connection | | `status` | string | Current status of the directory synchronization process | | `updated_at` | string | Timestamp of the most recent update to the directory connection | | `occurred_at` | string | Timestamp of when the event occurred | ## Directory User Events [Section titled “Directory User Events”](#directory-user-events) ### `organization.directory.user_created` [Section titled “organization.directory.user\_created”](#organizationdirectoryuser_created) This webhook is triggered when a new directory user is created. The event type is `organization.directory.user_created` organization.directory.user\_created ```json 1 { 2 "spec_version": "1", 3 "id": "evt_53891546994442316", 4 "type": "organization.directory.user_created", 5 "occurred_at": "2025-01-06T18:44:25.153954Z", 6 "environment_id": "env_53814739859406915", 7 "organization_id": "org_53879494091473415", 8 "object": "DirectoryUser", 9 "data": { 10 "active": true, 11 "cost_center": "QAUZJUHSTYCN", 12 "custom_attributes": { 13 "mobile_phone_number": "1-579-4072" 14 }, 15 "department": "HNXJPGISMIFN", 16 "division": "MJFUEYJOKICN", 17 "dp_id": "", 18 "email": "flavio@runolfsdottir.co.duk", 19 "employee_id": "AWNEDTILGaIZN", 20 "family_name": "Jaquelin", 21 "given_name": "Dayton", 22 "groups": [ 23 { 24 "id": "dirgroup_12312312312312", 25 "name": "Group Name" 26 } 27 ], 28 "id": "diruser_53891546960887884", 29 "language": "se", 30 "locale": "LLWLEWESPLDC", 31 "name": "QURGUZZDYMFU", 32 "nickname": "DTUODYKGFPPC", 33 "organization": "AUIITQVUQGVH", 34 "organization_id": "org_53879494091473415", 35 "phone_number": "1-579-4072", 36 "preferred_username": "kuntala1233a", 37 "profile": "YMIUQUHKGVAX", 38 "raw_attributes": {}, 39 "title": "FKQBHCWJXZSC", 40 "user_type": "RBQFJSQEFAEH", 41 "zoneinfo": "America/Araguaina", 42 "roles": [ 43 { 44 "role_name": "billing_admin" 45 } 46 ] 47 } 48 } ``` | Field | Type | Description | | -------------------- | ------- | ---------------------------------------------------------------------------------- | | `id` | string | Unique ID of the Directory User | | `organization_id` | string | Unique ID of the Organization to which this directory user belongs | | `dp_id` | string | Unique ID of the User in the Directory Provider (IdP) system | | `preferred_username` | string | Preferred username of the directory user | | `email` | string | Email of the directory user | | `active` | boolean | Indicates if the directory user is active | | `name` | string | Fully formatted name of the directory user | | `roles` | array | Array of roles assigned to the directory user | | `groups` | array | Array of groups to which the directory user belongs | | `given_name` | string | Given name of the directory user | | `family_name` | string | Family name of the directory user | | `nickname` | string | Nickname of the directory user | | `picture` | string | URL of the directory user’s profile picture | | `phone_number` | string | Phone number of the directory user | | `address` | object | Address of the directory user | | `custom_attributes` | object | Custom attributes of the directory user | | `raw_attributes` | object | Raw attributes of the directory user as received from the Directory Provider (IdP) | ### `organization.directory.user_updated` [Section titled “organization.directory.user\_updated”](#organizationdirectoryuser_updated) This webhook is triggered when a directory user is updated. The event type is `organization.directory.user_updated` organization.directory.user\_updated ```json 1 { 2 "spec_version": "1", 3 "id": "evt_53891546994442316", 4 "type": "organization.directory.user_updated", 5 "occurred_at": "2025-01-06T18:44:25.153954Z", 6 "environment_id": "env_53814739859406915", 7 "organization_id": "org_53879494091473415", 8 "object": "DirectoryUser", 9 "data": { 10 "id": "diruser_12312312312312", 11 "organization_id": "org_53879494091473415", 12 "dp_id": "", 13 "preferred_username": "", 14 "email": "john.doe@example.com", 15 "active": true, 16 "name": "John Doe", 17 "roles": [ 18 { 19 "role_name": "billing_admin" 20 } 21 ], 22 "groups": [ 23 { 24 "id": "dirgroup_12312312312312", 25 "name": "Group Name" 26 } 27 ], 28 "given_name": "John", 29 "family_name": "Doe", 30 "nickname": "Jhonny boy", 31 "picture": "https://image.com/profile.jpg", 32 "phone_number": "1234567892", 33 "address": { 34 "postal_code": "64112", 35 "state": "Missouri", 36 "formatted": "123, Oxford Lane, Kansas City, Missouri, 64112" 37 }, 38 "custom_attributes": { 39 "attribute1": "value1", 40 "attribute2": "value2" 41 }, 42 "raw_attributes": {} 43 } 44 } ``` | Field | Type | Description | | -------------------- | ------- | ---------------------------------------------------------------------------------- | | `id` | string | Unique ID of the Directory User | | `organization_id` | string | Unique ID of the Organization to which this directory user belongs | | `dp_id` | string | Unique ID of the User in the Directory Provider (IdP) system | | `preferred_username` | string | Preferred username of the directory user | | `email` | string | Email of the directory user | | `active` | boolean | Indicates if the directory user is active | | `name` | string | Fully formatted name of the directory user | | `roles` | array | Array of roles assigned to the directory user | | `groups` | array | Array of groups to which the directory user belongs | | `given_name` | string | Given name of the directory user | | `family_name` | string | Family name of the directory user | | `nickname` | string | Nickname of the directory user | | `picture` | string | URL of the directory user’s profile picture | | `phone_number` | string | Phone number of the directory user | | `address` | object | Address of the directory user | | `custom_attributes` | object | Custom attributes of the directory user | | `raw_attributes` | object | Raw attributes of the directory user as received from the Directory Provider (IdP) | ### `organization.directory.user_deleted` [Section titled “organization.directory.user\_deleted”](#organizationdirectoryuser_deleted) This webhook is triggered when a directory user is deleted. The event type is `organization.directory.user_deleted` organization.directory.user\_deleted ```json 1 { 2 "spec_version": "1", 3 "id": "evt_53891546994442316", 4 "type": "organization.directory.user_deleted", 5 "occurred_at": "2025-01-06T18:44:25.153954Z", 6 "environment_id": "env_53814739859406915", 7 "organization_id": "org_53879494091473415", 8 "object": "DirectoryUser", 9 "data": { 10 "id": "diruser_12312312312312", 11 "organization_id": "org_12312312312312", 12 "dp_id": "", 13 "email": "john.doe@example.com" 14 } 15 } ``` | Field | Type | Description | | ----------------- | ------ | ------------------------------------------------------------------ | | `id` | string | Unique ID of the Directory User | | `organization_id` | string | Unique ID of the Organization to which this directory user belongs | | `dp_id` | string | Unique ID of the User in the Directory Provider (IdP) system | | `email` | string | Email of the directory user | ## Directory Group Events [Section titled “Directory Group Events”](#directory-group-events) ### `organization.directory.group_created` [Section titled “organization.directory.group\_created”](#organizationdirectorygroup_created) This webhook is triggered when a new directory group is created. The event type is `organization.directory.group_created` organization.directory.group\_created ```json 1 { 2 "spec_version": "1", 3 "id": "evt_38862741515010639", 4 "environment_id": "env_32080745237316098", 5 "object": "DirectoryGroup", 6 "occurred_at": "2024-09-25T02:26:39.036398577Z", 7 "organization_id": "org_38609339635728478", 8 "type": "organization.directory.group_created", 9 "data": { 10 "directory_id": "dir_38610496391217780", 11 "display_name": "Avengers", 12 "external_id": null, 13 "id": "dirgroup_38862741498233423", 14 "organization_id": "org_38609339635728478", 15 "raw_attributes": {} 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------ | --------------------------------------------------------- | | `directory_id` | string | Unique identifier for the directory | | `display_name` | string | Display name of the directory group | | `external_id` | null | External identifier for the group, null if not specified | | `id` | string | Unique identifier for the directory group | | `organization_id` | string | Identifier for the organization associated with the group | | `raw_attributes` | object | Raw attributes of the directory provider | ### `organization.directory.group_updated` [Section titled “organization.directory.group\_updated”](#organizationdirectorygroup_updated) This webhook is triggered when a directory group is updated. The event type is `organization.directory.group_updated` organization.directory.group\_updated ```json 1 { 2 "spec_version": "1", 3 "id": "evt_38864948910162368", 4 "organization_id": "org_38609339635728478", 5 "type": "organization.directory.group_updated", 6 "environment_id": "env_32080745237316098", 7 "object": "DirectoryGroup", 8 "occurred_at": "2024-09-25T02:48:34.745030921Z", 9 "data": { 10 "directory_id": "dir_38610496391217780", 11 "display_name": "Avengers", 12 "external_id": "", 13 "id": "dirgroup_38862741498233423", 14 "organization_id": "org_38609339635728478", 15 "raw_attributes": {} 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------ | --------------------------------------------------------- | | `directory_id` | string | Unique identifier for the directory | | `display_name` | string | Display name of the directory group | | `external_id` | null | External identifier for the group, null if not specified | | `id` | string | Unique identifier for the directory group | | `organization_id` | string | Identifier for the organization associated with the group | | `raw_attributes` | object | Raw attributes of the directory group | ### `organization.directory.group_deleted` [Section titled “organization.directory.group\_deleted”](#organizationdirectorygroup_deleted) This webhook is triggered when a directory group is deleted. The event type is `organization.directory.group_deleted` organization.directory.group\_deleted ```json 1 { 2 "spec_version": "1", 3 "id": "evt_40650399597723966", 4 "environment_id": "env_12205603854221623", 5 "object": "DirectoryGroup", 6 "occurred_at": "2024-10-07T10:25:26.289331747Z", 7 "organization_id": "org_39802449573184223", 8 "type": "organization.directory.group_deleted", 9 "data": { 10 "directory_id": "dir_39802485862301855", 11 "display_name": "Admins", 12 "dp_id": "7c66a173-79c6-4270-ac78-8f35a8121e0a", 13 "id": "dirgroup_40072007005503806", 14 "organization_id": "org_39802449573184223", 15 "raw_attributes": {} 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------ | ------------------------------------------------------------------- | | `directory_id` | string | Unique identifier for the directory | | `display_name` | string | Display name of the directory group | | `dp_id` | string | Unique identifier for the group in the directory provider system | | `id` | string | Unique identifier for the directory group | | `organization_id` | string | Identifier for the organization associated with the group | | `raw_attributes` | object | Raw attributes of the directory group as received from the provider |
---
# DOCUMENT BOUNDARY
---
# Organization events
> Explore the webhook events related to organization operations in Scalekit, including creation, updates, and deletions.
This page documents the webhook events related to organization operations in Scalekit. *** ## Organization events [Section titled “Organization events”](#organization-events) ### `organization.created` [Section titled “organization.created”](#organizationcreated) This webhook is triggered when a new organization is created. The event type is `organization.created` organization.created ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_1234567890", 4 "object": "Organization", 5 "occurred_at": "2024-01-15T10:30:00.123456789Z", 6 "organization_id": "org_1234567890", 7 "spec_version": "1", 8 "type": "organization.created", 9 "data": { 10 "create_time": "2025-12-09T09:25:02.02Z", 11 "display_name": "AcmeCorp", 12 "external_id": "org_external_123", 13 "id": "org_1234567890", 14 "metadata": null, 15 "region_code": "US", 16 "update_time": "2025-12-09T09:25:02.025330364Z", 17 "settings": { 18 "features": [ 19 { 20 "enabled": true, 21 "name": "sso" 22 }, 23 { 24 "enabled": false, 25 "name": "dir_sync" 26 } 27 ] 28 } 29 } 30 } ``` | Field | Type | Description | | ------------------- | -------------- | ----------------------------------------------------------------------------- | | `id` | string | Unique identifier for the organization | | `external_id` | string \| null | External identifier for the organization, if provided | | `display_name` | string \| null | Name of the organization, if provided | | `region_code` | string \| null | Geographic region code for the organization (US, EU), currently limited to US | | `create_time` | string | Timestamp of when the organization was created | | `update_time` | string \| null | Timestamp of when the organization was last updated | | `metadata` | object \| null | Additional metadata associated with the organization | | `settings` | object \| null | Organization settings including feature flags (sso, dir\_sync) | | `settings.features` | array | Array of feature objects with enabled status and name | ### `organization.updated` [Section titled “organization.updated”](#organizationupdated) This webhook is triggered when an organization is updated. The event type is `organization.updated` organization.updated ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_2345678901", 4 "object": "Organization", 5 "occurred_at": "2024-01-15T10:35:00.123456789Z", 6 "organization_id": "org_1234567890", 7 "spec_version": "1", 8 "type": "organization.updated", 9 "data": { 10 "create_time": "2025-12-09T09:25:02.02Z", 11 "display_name": "AcmeCorp", 12 "external_id": "org_external_123", 13 "id": "org_1234567890", 14 "metadata": null, 15 "region_code": "US", 16 "update_time": "2025-12-09T09:25:02.025330364Z", 17 "settings": { 18 "features": [ 19 { 20 "enabled": true, 21 "name": "sso" 22 }, 23 { 24 "enabled": false, 25 "name": "dir_sync" 26 } 27 ] 28 } 29 } 30 } ``` | Field | Type | Description | | ------------------- | -------------- | ----------------------------------------------------------------------------- | | `id` | string | Unique identifier for the organization | | `external_id` | string \| null | External identifier for the organization, if provided | | `display_name` | string \| null | Name of the organization, if provided | | `region_code` | string \| null | Geographic region code for the organization (US, EU), currently limited to US | | `create_time` | string | Timestamp of when the organization was created | | `update_time` | string \| null | Timestamp of when the organization was last updated | | `metadata` | object \| null | Additional metadata associated with the organization | | `settings` | object \| null | Organization settings including feature flags (sso, dir\_sync) | | `settings.features` | array | Array of feature objects with enabled status and name | ### `organization.deleted` [Section titled “organization.deleted”](#organizationdeleted) This webhook is triggered when an organization is deleted. The event type is `organization.deleted` organization.deleted ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_3456789012", 4 "object": "Organization", 5 "occurred_at": "2024-01-15T10:40:00.123456789Z", 6 "organization_id": "org_1234567890", 7 "spec_version": "1", 8 "type": "organization.deleted", 9 "data": { 10 "create_time": "2025-12-09T09:25:02.02Z", 11 "deleted_at": "2025-12-09T10:25:45.337417Z", 12 "display_name": "AcmeCorp", 13 "external_id": "org_external_123", 14 "id": "org_1234567890", 15 "metadata": null, 16 "region_code": "US", 17 "update_time": "2025-12-09T09:25:02.025330364Z", 18 "settings": { 19 "features": [ 20 { 21 "enabled": true, 22 "name": "sso" 23 }, 24 { 25 "enabled": false, 26 "name": "dir_sync" 27 } 28 ] 29 } 30 } 31 } ``` | Field | Type | Description | | ------------------- | -------------- | ----------------------------------------------------------------------------- | | `id` | string | Unique identifier for the organization | | `external_id` | string \| null | External identifier for the organization, if provided | | `display_name` | string \| null | Name of the organization, if provided | | `region_code` | string \| null | Geographic region code for the organization (US, EU), currently limited to US | | `create_time` | string | Timestamp of when the organization was created | | `deleted_at` | string \| null | Timestamp of when the organization was deleted | | `update_time` | string \| null | Timestamp of when the organization was last updated | | `metadata` | object \| null | Additional metadata associated with the organization | | `settings` | object \| null | Organization settings including feature flags (sso, dir\_sync) | | `settings.features` | array | Array of feature objects with enabled status and name |
---
# DOCUMENT BOUNDARY
---
# Permission events
> Explore the webhook events related to permission operations in Scalekit, including creation, updates, and deletions.
This page documents the webhook events related to permission operations in Scalekit. *** ## Permission events [Section titled “Permission events”](#permission-events) ### `permission.created` [Section titled “permission.created”](#permissioncreated) This webhook is triggered when a new permission is created. The event type is `permission.created` permission.created ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_1234567890", 4 "object": "Permission", 5 "occurred_at": "2024-01-15T10:30:00.123456789Z", 6 "spec_version": "1", 7 "type": "permission.created", 8 "data": { 9 "description": "Permission to manage data", 10 "id": "perm_1234567890", 11 "name": "data:manage" 12 } 13 } ``` | Field | Type | Description | | ------------- | ------ | ----------------------------------------- | | `id` | string | Unique identifier for the permission | | `name` | string | Unique name identifier for the permission | | `description` | string | Description of what the permission allows | ### `permission.updated` [Section titled “permission.updated”](#permissionupdated) This webhook is triggered when a permission is updated. The event type is `permission.updated` permission.updated ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_2345678901", 4 "object": "Permission", 5 "occurred_at": "2024-01-15T10:35:00.123456789Z", 6 "spec_version": "1", 7 "type": "permission.updated", 8 "data": { 9 "description": "Updated permission to manage all data", 10 "id": "perm_1234567890", 11 "name": "data:manage" 12 } 13 } ``` | Field | Type | Description | | ------------- | ------ | ----------------------------------------- | | `id` | string | Unique identifier for the permission | | `name` | string | Unique name identifier for the permission | | `description` | string | Description of what the permission allows | ### `permission.deleted` [Section titled “permission.deleted”](#permissiondeleted) This webhook is triggered when a permission is deleted. The event type is `permission.deleted` permission.deleted ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_3456789012", 4 "object": "Permission", 5 "occurred_at": "2024-01-15T10:40:00.123456789Z", 6 "spec_version": "1", 7 "type": "permission.deleted", 8 "data": { 9 "description": "Updated permission to manage all data", 10 "id": "perm_1234567890", 11 "name": "data:manage" 12 } 13 } ``` | Field | Type | Description | | ------------- | ------ | ------------------------------------------------- | | `id` | string | Unique identifier for the deleted permission | | `name` | string | Unique name identifier for the deleted permission | | `description` | string | Description of what the permission allowed |
---
# DOCUMENT BOUNDARY
---
# Role events
> Explore the webhook events related to role operations in Scalekit, including creation, updates, and deletions.
This page documents the webhook events related to role operations in Scalekit. *** ## Role events [Section titled “Role events”](#role-events) ### `role.created` [Section titled “role.created”](#rolecreated) This webhook is triggered when a new role is created. The event type is `role.created` role.created ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_1234567890", 4 "object": "Role", 5 "occurred_at": "2024-01-15T10:30:00.123456789Z", 6 "spec_version": "1", 7 "type": "role.created", 8 "data": { 9 "description": "Viewer role with read-only access", 10 "display_name": "Viewer", 11 "extends": "member", 12 "id": "role_1234567890", 13 "name": "viewer" 14 } 15 } ``` | Field | Type | Description | | -------------- | ------ | -------------------------------------------- | | `id` | string | Unique identifier for the role | | `name` | string | Unique name identifier for the role | | `display_name` | string | Human-readable display name for the role | | `description` | string | Description of the role and its purpose | | `extends` | string | Name of the role that this role extends from | ### `role.updated` [Section titled “role.updated”](#roleupdated) This webhook is triggered when a role is updated. The event type is `role.updated` role.updated ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_2345678901", 4 "object": "Role", 5 "occurred_at": "2024-01-15T10:35:00.123456789Z", 6 "spec_version": "1", 7 "type": "role.updated", 8 "data": { 9 "description": "Updated viewer role with limited permissions", 10 "display_name": "Viewer", 11 "extends": "member", 12 "id": "role_1234567890", 13 "name": "viewer" 14 } 15 } ``` | Field | Type | Description | | -------------- | ------ | -------------------------------------------- | | `id` | string | Unique identifier for the role | | `name` | string | Unique name identifier for the role | | `display_name` | string | Human-readable display name for the role | | `description` | string | Description of the role and its purpose | | `extends` | string | Name of the role that this role extends from | ### `role.deleted` [Section titled “role.deleted”](#roledeleted) This webhook is triggered when a role is deleted. The event type is `role.deleted` role.deleted ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_3456789012", 4 "object": "Role", 5 "occurred_at": "2024-01-15T10:40:00.123456789Z", 6 "spec_version": "1", 7 "type": "role.deleted", 8 "data": { 9 "description": "Updated viewer role with limited permissions", 10 "display_name": "Viewer", 11 "extends": "member", 12 "id": "role_1234567890", 13 "name": "viewer" 14 } 15 } ``` | Field | Type | Description | | -------------- | ------ | ------------------------------------------------ | | `id` | string | Unique identifier for the deleted role | | `name` | string | Unique name identifier for the deleted role | | `display_name` | string | Human-readable display name for the deleted role | | `description` | string | Description of the role that was deleted | | `extends` | string | Name of the role that this role extends from |
---
# DOCUMENT BOUNDARY
---
# Enterprise SSO events
> Explore the webhook events related to Enterprise SSO operations in Scalekit, including connection creation, enabling, disabling, and deletion.
This page documents the webhook events related to Enterprise SSO connection operations in Scalekit. *** ## SSO connection events [Section titled “SSO connection events”](#sso-connection-events) ### `organization.sso_created` [Section titled “organization.sso\_created”](#organizationsso_created) This webhook is triggered when a new SSO connection is created for an organization. The event type is `organization.sso_created` organization.sso\_created ```json 1 { 2 "spec_version": "1", 3 "id": "evt_94567862441607493", 4 "object": "Connection", 5 "environment_id": "env_74418471961625391", 6 "occurred_at": "2025-10-14T09:27:18.488720586Z", 7 "organization_id": "org_83544995172188677", 8 "type": "organization.sso_created", 9 "data": { 10 "id": "conn_94567862424830277", 11 "organization_id": "org_83544995172188677", 12 "connection_type": "OIDC", 13 "provider": "OKTA" 14 } 15 } ``` | Field | Type | Description | | ----------------- | ------ | --------------------------------------------------------------- | | `id` | string | Unique identifier for the SSO connection | | `organization_id` | string | Identifier for the organization associated with this connection | | `connection_type` | string | Type of SSO connection (OIDC, SAML, etc.) | | `provider` | string | Identity provider for the SSO connection | ### `organization.sso_enabled` [Section titled “organization.sso\_enabled”](#organizationsso_enabled) This webhook is triggered when an SSO connection is enabled for an organization. The event type is `organization.sso_enabled` organization.sso\_enabled ```json 1 { 2 "spec_version": "1", 3 "id": "evt_94568078213382471", 4 "object": "Connection", 5 "environment_id": "env_74418471961625391", 6 "occurred_at": "2025-10-14T09:29:27.098914861Z", 7 "organization_id": "org_83544995172188677", 8 "type": "organization.sso_enabled", 9 "data": { 10 "id": "conn_94567862424830277", 11 "organization_id": "org_83544995172188677", 12 "connection_type": "OIDC", 13 "provider": "OKTA", 14 "enabled": true, 15 "status": "COMPLETED" 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------- | ------------------------------------------------------------------- | | `id` | string | Unique identifier for the SSO connection | | `organization_id` | string | Identifier for the organization associated with this connection | | `connection_type` | string | Type of SSO connection (OIDC, SAML, etc.) | | `provider` | string | Identity provider for the SSO connection | | `enabled` | boolean | Indicates whether the SSO connection is enabled (true in this case) | | `status` | string | Current status of the SSO connection configuration | ### `organization.sso_disabled` [Section titled “organization.sso\_disabled”](#organizationsso_disabled) This webhook is triggered when an SSO connection is disabled for an organization. The event type is `organization.sso_disabled` organization.sso\_disabled ```json 1 { 2 "spec_version": "1", 3 "id": "evt_94557976165089560", 4 "object": "Connection", 5 "environment_id": "env_74418471961625391", 6 "occurred_at": "2025-10-14T07:49:05.809554456Z", 7 "organization_id": "org_83544995172188677", 8 "type": "organization.sso_disabled", 9 "data": { 10 "id": "conn_83545002856153607", 11 "organization_id": "org_83544995172188677", 12 "connection_type": "OIDC", 13 "provider": "OKTA", 14 "enabled": false, 15 "status": "COMPLETED" 16 } 17 } ``` | Field | Type | Description | | ----------------- | ------- | -------------------------------------------------------------------- | | `id` | string | Unique identifier for the SSO connection | | `organization_id` | string | Identifier for the organization associated with this connection | | `connection_type` | string | Type of SSO connection (OIDC, SAML, etc.) | | `provider` | string | Identity provider for the SSO connection | | `enabled` | boolean | Indicates whether the SSO connection is enabled (false in this case) | | `status` | string | Current status of the SSO connection configuration | ### `organization.sso_deleted` [Section titled “organization.sso\_deleted”](#organizationsso_deleted) This webhook is triggered when an SSO connection is deleted for an organization. The event type is `organization.sso_deleted` organization.sso\_deleted ```json 1 { 2 "spec_version": "1", 3 "id": "evt_94557997639926040", 4 "object": "Connection", 5 "environment_id": "env_74418471961625391", 6 "occurred_at": "2025-10-14T07:49:18.604546332Z", 7 "organization_id": "org_83544995172188677", 8 "type": "organization.sso_deleted", 9 "data": { 10 "id": "conn_83545002856153607", 11 "organization_id": "org_83544995172188677", 12 "connection_type": "OIDC", 13 "provider": "OKTA" 14 } 15 } ``` | Field | Type | Description | | ----------------- | ------ | --------------------------------------------------------------- | | `id` | string | Unique identifier for the SSO connection | | `organization_id` | string | Identifier for the organization associated with this connection | | `connection_type` | string | Type of SSO connection (OIDC, SAML, etc.) | | `provider` | string | Identity provider for the SSO connection |
---
# DOCUMENT BOUNDARY
---
# User events
> Explore the webhook events related to user operations in Scalekit, including signup, login, logout, and organization membership events.
This page documents the webhook events related to user operations in Scalekit. *** ## User authentication events [Section titled “User authentication events”](#user-authentication-events) ### `user.signup` [Section titled “user.signup”](#usersignup) This webhook is triggered when a user signs up to create a new organization. The event type is `user.signup`. user.signup ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_1234567890", 4 "object": "OrgMembershipEvent", 5 "occurred_at": "2024-01-15T10:30:00.123456789Z", 6 "spec_version": "1", 7 "type": "user.signup", 8 "data": { 9 "organization": { 10 "id": "org_1234567890", 11 "create_time": "2025-12-09T10:19:05.48Z", 12 "display_name": "", 13 "external_id": null, 14 "id": "org_102690563312124938", 15 "metadata": null, 16 "region_code": "US", 17 "update_time": "2025-12-09T12:04:41.386974738Z", 18 "settings": { 19 "features": [ 20 { 21 "enabled": true, 22 "name": "sso" 23 }, 24 { 25 "enabled": true, 26 "name": "dir_sync" 27 } 28 ] 29 } 30 }, 31 "user": { 32 "create_time": "2025-12-09T12:04:41.39Z", 33 "email": "amit.ash1996@gmail.com", 34 "external_id": "", 35 "id": "usr_102701193205121289", 36 "metadata": {}, 37 "update_time": "2025-12-09T12:04:41.391988278Z", 38 "user_profile": { 39 "custom_attributes": null, 40 "email_verified": true, 41 "external_identities": null, 42 "family_name": "doe", 43 "gender": "", 44 "given_name": "John", 45 "groups": null, 46 "id": "usp_102701193205186825", 47 "locale": "", 48 "metadata": {}, 49 "name": "John Doe", 50 "phone_number": "", 51 "phone_number_verified": false, 52 "picture": "https://lh3.googleusercontent.com/a/abcdef", 53 "preferred_username": "" 54 } 55 } 56 } 57 } ``` | Field | Type | Description | | -------------------------------- | -------------- | ----------------------------------------------------------------------------- | | `organization` | object | Details of organization that is created on signup | | `organization.id` | string | Unique identifier for the organization | | `organization.external_id` | string \| null | External identifier for the organization, if provided | | `organization.display_name` | string \| null | Name of the organization, if provided | | `organization.region_code` | string \| null | Geographic region code for the organization (US, EU), currently limited to US | | `organization.create_time` | string | Timestamp of when the organization was created | | `organization.update_time` | string \| null | Timestamp of when the organization was last updated | | `organization.metadata` | object \| null | Additional metadata associated with the organization | | `organization.settings` | object \| null | Organization settings including feature flags (sso, dir\_sync) | | `organization.settings.features` | array | Array of feature objects with enabled status and name | | `user` | object | User details for the signed-up user | | `user.id` | string | Unique identifier for the user | | `user.email` | string | Email address of the user | | `user.external_id` | string \| null | External identifier for the user, if provided | | `user.create_time` | string | Timestamp of when the user was created | | `user.update_time` | string | Timestamp of when the user was last updated | | `user.metadata` | string | Custom key-value pairs storing additional user context | | `user.user_profile` | object | User profile information | ### `user.login` [Section titled “user.login”](#userlogin) This webhook is triggered when a user logs in and a session is created. The event type is `user.login`. user.login ```json 1 { 2 "environment_id": "env_96736846679245078", 3 "id": "evt_102701193859432713", 4 "object": "UserLoginEvent", 5 "occurred_at": "2025-12-09T12:04:41.781873312Z", 6 "spec_version": "1", 7 "type": "user.login", 8 "data": { 9 "user": { 10 "create_time": "2025-12-09T12:04:41.39Z", 11 "email": "john.doe@acmecorp.com", 12 "external_id": "ext_123456789", 13 "id": "usr_123456789", 14 "last_login_time": "2025-12-09T12:04:41.48Z", 15 "metadata": {}, 16 "update_time": "2025-12-09T12:04:41.391988Z", 17 "user_profile": { 18 "custom_attributes": null, 19 "email_verified": true, 20 "external_identities": [ 21 { 22 "connection_id": "conn_97896332307464201", 23 "connection_provider": "GOOGLE", 24 "connection_type": "OAUTH", 25 "connection_user_id": "105055379523565727691", 26 "created_time": "2025-12-09T12:04:41.47Z", 27 "is_social": true, 28 "last_login_time": "2025-12-09T12:04:41.469311Z", 29 "last_synced_time": "2025-12-09T12:04:41.469311Z" 30 } 31 ], 32 "family_name": "Doe", 33 "gender": "", 34 "given_name": "John", 35 "groups": null, 36 "id": "usp_102701193205186825", 37 "locale": "", 38 "metadata": {}, 39 "name": "John Doe", 40 "phone_number": "", 41 "phone_number_verified": false, 42 "picture": "https://lh3.googleusercontent.com/a/abcdef", 43 "preferred_username": "" 44 } 45 }, 46 "user_session": { 47 "absolute_expires_at": "2026-01-08T12:04:41.737394Z", 48 "authenticated_organizations": ["org_102701193188409609"], 49 "created_at": "2025-12-09T12:04:41.48Z", 50 "expired_at": null, 51 "idle_expires_at": "2025-12-16T12:04:41.737395Z", 52 "last_active_at": "2025-12-09T12:04:41.747206Z", 53 "logout_at": null, 54 "organization_id": "org_102701193188409609", 55 "session_id": "ses_102701193356116233", 56 "status": "ACTIVE", 57 "updated_at": "2025-12-09T12:04:41.748512Z", 58 "user_id": "usr_102701193205121289", 59 "device": { 60 "browser": "Chrome", 61 "browser_version": "142.0.0.0", 62 "device_type": "Desktop", 63 "ip": "152.59.144.211", 64 "location": { 65 "city": "Patna", 66 "latitude": "25.594095", 67 "longitude": "85.137564", 68 "region": "IN", 69 "region_subdivision": "INBR" 70 }, 71 "os": "macOS", 72 "os_version": "10.15.7", 73 "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36" 74 } 75 } 76 } 77 } ``` | Field | Type | Description | | ------------------------------------------ | -------------- | ---------------------------------------------------------------------------------------------- | | `user` | object | User details for the logged-in user | | `user.id` | string | Unique identifier for the user | | `user.email` | string | Email address of the user | | `user.external_id` | string \| null | External identifier for the user, if provided | | `user.create_time` | string | Timestamp of when the user was created | | `user.update_time` | string | Timestamp of when the user was last updated | | `user.user_profile` | object | User profile information | | `user_session.absolute_expires_at` | string | Hard expiration timestamp for the session regardless of user activity | | `user_session.authenticated_organizations` | array | List of organization IDs that have been authenticated for this user within the current session | | `user_session.created_at` | string | Timestamp indicating when the session was created | | `user_session.expired_at` | string \| null | Timestamp when the session was terminated | | `user_session.idle_expires_at` | string | Projected expiration timestamp if the session remains idle without user activity | | `user_session.last_active_at` | string | Timestamp of the most recent user activity detected in this session | | `user_session.logout_at` | string \| null | Timestamp when the user explicitly logged out from the session | | `user_session.organization_id` | string | Organization ID for the user’s current active organization in this session | | `user_session.session_id` | string | Unique identifier for the session | | `user_session.status` | string | Current operational status of the session. Possible values: ‘active’ | | `user_session.updated_at` | string | Timestamp indicating when the session was last updated | | `user_session.user_id` | string | User ID for the user who owns this session | | `user_session.device` | object | Device metadata associated with this session | ### `user.logout` [Section titled “user.logout”](#userlogout) This webhook is triggered when a user’s session is terminated. The session termination could be due to user-initiated logout, idle or absolute session expiration, admin-administered session revocation. user.logout ```json 1 { 2 "environment_id": "env_96736846679245078", 3 "id": "evt_102708230123160586", 4 "object": "UserLogoutEvent", 5 "occurred_at": "2025-12-09T13:14:35.722070822Z", 6 "spec_version": "1", 7 "type": "user.logout", 8 "data": { 9 "user": { 10 "create_time": "2025-12-09T12:04:41.39Z", 11 "email": "john.doe@acmecorp.com", 12 "external_id": "ext_123456789", 13 "id": "usr_123456789", 14 "last_login_time": "2025-12-09T12:04:41.48Z", 15 "metadata": {}, 16 "update_time": "2025-12-09T12:04:41.391988Z", 17 "user_profile": { 18 "custom_attributes": null, 19 "email_verified": true, 20 "external_identities": [ 21 { 22 "connection_id": "conn_97896332307464201", 23 "connection_provider": "GOOGLE", 24 "connection_type": "OAUTH", 25 "connection_user_id": "105055379523565727691", 26 "created_time": "2025-12-09T12:04:41.47Z", 27 "is_social": true, 28 "last_login_time": "2025-12-09T12:04:41.469311Z", 29 "last_synced_time": "2025-12-09T12:04:41.469311Z" 30 } 31 ], 32 "family_name": "Charles", 33 "gender": "", 34 "given_name": "Dwayne", 35 "groups": null, 36 "id": "usp_102701193205186825", 37 "locale": "", 38 "metadata": {}, 39 "name": "Dwayne Charles", 40 "phone_number": "", 41 "phone_number_verified": false, 42 "picture": "https://lh3.googleusercontent.com/a/abcdef", 43 "preferred_username": "" 44 } 45 }, 46 "user_session": { 47 "absolute_expires_at": "2026-01-08T12:04:41.737394Z", 48 "authenticated_organizations": ["org_102701193188409609"], 49 "created_at": "2025-12-09T12:04:41.48Z", 50 "expired_at": null, 51 "idle_expires_at": "2025-12-16T12:04:41.737395Z", 52 "last_active_at": "2025-12-09T12:04:41.747206Z", 53 "logout_at": null, 54 "organization_id": "org_102701193188409609", 55 "session_id": "ses_102701193356116233", 56 "status": "ACTIVE", 57 "updated_at": "2025-12-09T12:04:41.748512Z", 58 "user_id": "usr_102701193205121289", 59 "device": { 60 "browser": "Chrome", 61 "browser_version": "142.0.0.0", 62 "device_type": "Desktop", 63 "ip": "152.59.144.211", 64 "location": { 65 "city": "Patna", 66 "latitude": "25.594095", 67 "longitude": "85.137564", 68 "region": "IN", 69 "region_subdivision": "INBR" 70 }, 71 "os": "macOS", 72 "os_version": "10.15.7", 73 "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36" 74 } 75 } 76 } 77 } ``` | Field | Type | Description | | ------------------------------------------ | -------------- | ---------------------------------------------------------------------------------------------- | | `user` | object | User details for the logged-in user | | `user.id` | string | Unique identifier for the user | | `user.email` | string | Email address of the user | | `user.external_id` | string \| null | External identifier for the user, if provided | | `user.create_time` | string | Timestamp of when the user was created | | `user.update_time` | string | Timestamp of when the user was last updated | | `user.user_profile` | object | User profile information | | `user_session.absolute_expires_at` | string | Hard expiration timestamp for the session regardless of user activity | | `user_session.authenticated_organizations` | array | List of organization IDs that have been authenticated for this user within the current session | | `user_session.created_at` | string | Timestamp indicating when the session was created | | `user_session.expired_at` | string \| null | Timestamp when the session was terminated | | `user_session.idle_expires_at` | string | Projected expiration timestamp if the session remains idle without user activity | | `user_session.last_active_at` | string | Timestamp of the most recent user activity detected in this session | | `user_session.logout_at` | string \| null | Timestamp when the user explicitly logged out from the session | | `user_session.organization_id` | string | Organization ID for the user’s current active organization in this session | | `user_session.session_id` | string | Unique identifier for the session | | `user_session.status` | string | Current operational status of the session. Possible values: ‘expired’, ‘revoked’, ‘logout’ | | `user_session.updated_at` | string | Timestamp indicating when the session was last updated | | `user_session.user_id` | string | User ID for the user who owns this session | | `user_session.device` | object | Device metadata associated with this session | ## Organization membership events [Section titled “Organization membership events”](#organization-membership-events) ### `user.organization_invitation` [Section titled “user.organization\_invitation”](#userorganization_invitation) This webhook is triggered when a user is invited to join an organization. The event type is `user.organization_invitation`. user.organization\_invitation ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_4567890123", 4 "object": "OrgMembershipEvent", 5 "occurred_at": "2024-01-15T11:00:00.123456789Z", 6 "spec_version": "1", 7 "type": "user.organization_invitation", 8 "data": { 9 "organization": { 10 "id": "org_1234567890", 11 "create_time": "2025-12-09T10:19:05.48Z", 12 "display_name": "Acme Corp", 13 "external_id": "org_external_123", 14 "id": "org_102690563312124938", 15 "metadata": null, 16 "region_code": "US", 17 "update_time": "2025-12-09T12:04:41.386974738Z", 18 "settings": { 19 "features": [ 20 { 21 "enabled": true, 22 "name": "sso" 23 }, 24 { 25 "enabled": true, 26 "name": "dir_sync" 27 } 28 ] 29 } 30 }, 31 "user": { 32 "create_time": "2025-12-09T12:04:41.39Z", 33 "email": "john.doe@acmecorp.com", 34 "external_id": "ext_123456789", 35 "id": "usr_123456789", 36 "metadata": {}, 37 "update_time": "2025-12-09T12:04:41.391988Z", 38 "user_profile": { 39 "custom_attributes": null, 40 "email_verified": true, 41 "external_identities": [ 42 { 43 "connection_id": "conn_97896332307464201", 44 "connection_provider": "GOOGLE", 45 "connection_type": "OAUTH", 46 "connection_user_id": "105055379523565727691", 47 "created_time": "2025-12-09T12:04:41.47Z", 48 "is_social": true, 49 "last_login_time": "2025-12-09T12:04:41.469311Z", 50 "last_synced_time": "2025-12-09T12:04:41.469311Z" 51 } 52 ], 53 "family_name": "Doe", 54 "gender": "", 55 "given_name": "John", 56 "groups": null, 57 "id": "usp_102701193205186825", 58 "locale": "", 59 "metadata": {}, 60 "name": "John Doe", 61 "phone_number": "", 62 "phone_number_verified": false, 63 "picture": "https://lh3.googleusercontent.com/a/abcdef", 64 "preferred_username": "" 65 } 66 } 67 } 68 } ``` | Field | Type | Description | | -------------------------------- | -------------- | ----------------------------------------------------------------------------- | | `organization` | object | Organization details for the invitation | | `organization.id` | string | Unique identifier for the organization | | `organization.external_id` | string \| null | External identifier for the organization if provided | | `organization.display_name` | string \| null | Name of the organization, if provided | | `organization.region_code` | string \| null | Geographic region code for the organization (US, EU), currently limited to US | | `organization.create_time` | string | Timestamp of when the organization was created | | `organization.update_time` | string \| null | Timestamp of when the organization was last updated | | `organization.metadata` | object \| null | Additional metadata associated with the organization | | `organization.settings` | object \| null | Organization settings including feature flags (sso, dir\_sync) | | `organization.settings.features` | array | Array of feature objects with enabled status and name | | `user` | object | User details for the invited user | | `user.id` | string | Unique identifier for the invited user | | `user.email` | string | Email address of the invited user | | `user.external_id` | string \| null | External identifier for the user, if provided | | `user.create_time` | string | Timestamp of when the user was created | | `user.update_time` | string | Timestamp of when the user was last updated | | `user.user_profile` | object | User profile information | ### `user.organization_membership_created` [Section titled “user.organization\_membership\_created”](#userorganization_membership_created) This webhook is triggered when a user joins an organization. The event type is `user.organization_membership_created`. user.organization\_membership\_created ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_5678901234", 4 "object": "OrgMembershipEvent", 5 "occurred_at": "2024-01-15T11:05:00.123456789Z", 6 "spec_version": "1", 7 "type": "user.organization_membership_created", 8 "data": { 9 "organization": { 10 "id": "org_1234567890", 11 "create_time": "2025-12-09T10:19:05.48Z", 12 "display_name": "Acme Corp", 13 "external_id": "org_external_123", 14 "id": "org_102690563312124938", 15 "metadata": null, 16 "region_code": "US", 17 "update_time": "2025-12-09T12:04:41.386974738Z", 18 "settings": { 19 "features": [ 20 { 21 "enabled": true, 22 "name": "sso" 23 }, 24 { 25 "enabled": true, 26 "name": "dir_sync" 27 } 28 ] 29 } 30 }, 31 "user": { 32 "create_time": "2025-12-09T12:04:41.39Z", 33 "email": "john.doe@acmecorp.com", 34 "external_id": "ext_123456789", 35 "id": "usr_123456789", 36 "metadata": {}, 37 "update_time": "2025-12-09T12:04:41.391988Z", 38 "user_profile": { 39 "custom_attributes": null, 40 "email_verified": true, 41 "external_identities": [ 42 { 43 "connection_id": "conn_97896332307464201", 44 "connection_provider": "GOOGLE", 45 "connection_type": "OAUTH", 46 "connection_user_id": "105055379523565727691", 47 "created_time": "2025-12-09T12:04:41.47Z", 48 "is_social": true, 49 "last_login_time": "2025-12-09T12:04:41.469311Z", 50 "last_synced_time": "2025-12-09T12:04:41.469311Z" 51 } 52 ], 53 "family_name": "Doe", 54 "gender": "", 55 "given_name": "John", 56 "groups": null, 57 "id": "usp_102701193205186825", 58 "locale": "", 59 "metadata": {}, 60 "name": "John Doe", 61 "phone_number": "", 62 "phone_number_verified": false, 63 "picture": "https://lh3.googleusercontent.com/a/abcdef", 64 "preferred_username": "" 65 } 66 } 67 } 68 } ``` | Field | Type | Description | | -------------------------------- | -------------- | ----------------------------------------------------------------------------- | | `organization` | object | Details of the organization which the user has joined | | `organization.id` | string | Unique identifier for the organization | | `organization.external_id` | string \| null | External identifier for the organization if provided | | `organization.display_name` | string \| null | Name of the organization, if provided | | `organization.region_code` | string \| null | Geographic region code for the organization (US, EU), currently limited to US | | `organization.create_time` | string | Timestamp of when the organization was created | | `organization.update_time` | string \| null | Timestamp of when the organization was last updated | | `organization.metadata` | object \| null | Additional metadata associated with the organization | | `organization.settings` | object \| null | Organization settings including feature flags (sso, dir\_sync) | | `organization.settings.features` | array | Array of feature objects with enabled status and name | | `user` | object | User details for the user who joined the organization | | `user.id` | string | Unique identifier for the user | | `user.email` | string | Email address of the user | | `user.external_id` | string \| null | External identifier for the user, if provided | | `user.create_time` | string | Timestamp of when the user was created | | `user.update_time` | string | Timestamp of when the user was last updated | | `user.user_profile` | object | User profile information | ### `user.organization_membership_updated` [Section titled “user.organization\_membership\_updated”](#userorganization_membership_updated) This webhook is triggered when a user’s organization membership is updated, e.g., change of user’s role in an organization. The event type is `user.organization_membership_updated`. user.organization\_membership\_updated ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_6789012345", 4 "object": "OrgMembershipEvent", 5 "occurred_at": "2024-01-15T11:10:00.123456789Z", 6 "spec_version": "1", 7 "type": "user.organization_membership_updated", 8 "data": { 9 "organization": { 10 "id": "org_1234567890", 11 "create_time": "2025-12-09T10:19:05.48Z", 12 "display_name": "Acme Corp", 13 "external_id": "org_external_123", 14 "id": "org_102690563312124938", 15 "metadata": null, 16 "region_code": "US", 17 "update_time": "2025-12-09T12:04:41.386974738Z", 18 "settings": { 19 "features": [ 20 { 21 "enabled": true, 22 "name": "sso" 23 }, 24 { 25 "enabled": true, 26 "name": "dir_sync" 27 } 28 ] 29 } 30 }, 31 "user": { 32 "create_time": "2025-12-09T12:04:41.39Z", 33 "email": "john.doe@acmecorp.com", 34 "external_id": "ext_123456789", 35 "id": "usr_123456789", 36 "metadata": {}, 37 "update_time": "2025-12-09T12:04:41.391988Z", 38 "user_profile": { 39 "custom_attributes": null, 40 "email_verified": true, 41 "external_identities": [ 42 { 43 "connection_id": "conn_97896332307464201", 44 "connection_provider": "GOOGLE", 45 "connection_type": "OAUTH", 46 "connection_user_id": "105055379523565727691", 47 "created_time": "2025-12-09T12:04:41.47Z", 48 "is_social": true, 49 "last_login_time": "2025-12-09T12:04:41.469311Z", 50 "last_synced_time": "2025-12-09T12:04:41.469311Z" 51 } 52 ], 53 "family_name": "Doe", 54 "gender": "", 55 "given_name": "John", 56 "groups": null, 57 "id": "usp_102701193205186825", 58 "locale": "", 59 "metadata": {}, 60 "name": "John Doe", 61 "phone_number": "", 62 "phone_number_verified": false, 63 "picture": "https://lh3.googleusercontent.com/a/abcdef", 64 "preferred_username": "" 65 } 66 } 67 } 68 } ``` | Field | Type | Description | | -------------------------------- | -------------- | --------------------------------------------------------------------------------- | | `organization` | object | Details of the organization for which users’ membership details have been updated | | `organization.id` | string | Unique identifier for the organization | | `organization.external_id` | string \| null | External identifier for the organization if provided | | `organization.display_name` | string \| null | Name of the organization, if provided | | `organization.region_code` | string \| null | Geographic region code for the organization (US, EU), currently limited to US | | `organization.create_time` | string | Timestamp of when the organization was created | | `organization.update_time` | string \| null | Timestamp of when the organization was last updated | | `organization.metadata` | object \| null | Additional metadata associated with the organization | | `organization.settings` | object \| null | Organization settings including feature flags (sso, dir\_sync) | | `organization.settings.features` | array | Array of feature objects with enabled status and name | | `user` | object | User details for the user whose organization membership has been updated | | `user.id` | string | Unique identifier for the user | | `user.email` | string | Email address of the user | | `user.external_id` | string \| null | External identifier for the user, if provided | | `user.create_time` | string | Timestamp of when the user was created | | `user.update_time` | string | Timestamp of when the user was last updated | | `user.user_profile` | object | User profile information | ### `user.organization_membership_deleted` [Section titled “user.organization\_membership\_deleted”](#userorganization_membership_deleted) This webhook is triggered when a user is removed from an organization. The event type is `user.organization_membership_deleted`. user.organization\_membership\_deleted ```json 1 { 2 "environment_id": "env_1234567890", 3 "id": "evt_7890123456", 4 "object": "OrgMembershipEvent", 5 "occurred_at": "2024-01-15T11:15:00.123456789Z", 6 "spec_version": "1", 7 "type": "user.organization_membership_deleted", 8 "data": { 9 "organization": { 10 "id": "org_1234567890", 11 "create_time": "2025-12-09T10:19:05.48Z", 12 "display_name": "Acme Corp", 13 "external_id": "org_external_123", 14 "id": "org_102690563312124938", 15 "metadata": null, 16 "region_code": "US", 17 "update_time": "2025-12-09T12:04:41.386974738Z", 18 "settings": { 19 "features": [ 20 { 21 "enabled": true, 22 "name": "sso" 23 }, 24 { 25 "enabled": true, 26 "name": "dir_sync" 27 } 28 ] 29 } 30 }, 31 "user": { 32 "create_time": "2025-12-09T12:04:41.39Z", 33 "email": "john.doe@acmecorp.com", 34 "external_id": "ext_123456789", 35 "id": "usr_123456789", 36 "metadata": {}, 37 "update_time": "2025-12-09T12:04:41.391988Z", 38 "user_profile": { 39 "custom_attributes": null, 40 "email_verified": true, 41 "external_identities": [ 42 { 43 "connection_id": "conn_97896332307464201", 44 "connection_provider": "GOOGLE", 45 "connection_type": "OAUTH", 46 "connection_user_id": "105055379523565727691", 47 "created_time": "2025-12-09T12:04:41.47Z", 48 "is_social": true, 49 "last_login_time": "2025-12-09T12:04:41.469311Z", 50 "last_synced_time": "2025-12-09T12:04:41.469311Z" 51 } 52 ], 53 "family_name": "Doe", 54 "gender": "", 55 "given_name": "John", 56 "groups": null, 57 "id": "usp_102701193205186825", 58 "locale": "", 59 "metadata": {}, 60 "name": "John Doe", 61 "phone_number": "", 62 "phone_number_verified": false, 63 "picture": "https://lh3.googleusercontent.com/a/abcdef", 64 "preferred_username": "" 65 } 66 } 67 } 68 } ``` | Field | Type | Description | | -------------------------------- | -------------- | ----------------------------------------------------------------------------- | | `organization` | object | Details of the organization from which the user has been removed | | `organization.id` | string | Unique identifier for the organization | | `organization.external_id` | string \| null | External identifier for the organization if provided | | `organization.display_name` | string \| null | Name of the organization, if provided | | `organization.region_code` | string \| null | Geographic region code for the organization (US, EU), currently limited to US | | `organization.create_time` | string | Timestamp of when the organization was created | | `organization.update_time` | string \| null | Timestamp of when the organization was last updated | | `organization.metadata` | object \| null | Additional metadata associated with the organization | | `organization.settings` | object \| null | Organization settings including feature flags (sso, dir\_sync) | | `organization.settings.features` | array | Array of feature objects with enabled status and name | | `user` | object | User details for the user who has been removed from an organization | | `user.id` | string | Unique identifier for the user | | `user.email` | string | Email address of the user | | `user.external_id` | string \| null | External identifier for the user, if provided | | `user.create_time` | string | Timestamp of when the user was created | | `user.update_time` | string | Timestamp of when the user was last updated | | `user.user_profile` | object | User profile information |