# Implement organization switcher

Organization switching lets users access multiple organizations or workspaces within your application. This guide shows you how to implement organization switching using Scalekit's built-in switcher or by building your own organization switcher in your application.

This feature is essential for B2B applications where users may belong to several organizations simultaneously. Common scenarios include:

- **Personal workspace to corporate workspace**: Users sign up with their organization's email address, creating their personal workspace. Later, when their organization subscribes to your app, a new corporate workspace is created (for example, "AcmeCorp workspace").
- **Multi-organization contractors**: External consultants or contractors who belong to multiple organizations, each with their own SSO authentication policies. These users need to switch between different client organizations while maintaining secure access to each workspace.

![](@/assets/docs/fsa/org-switcher/1-switcher.png)

## Default organization switching behavior

When users belong to multiple organizations, Scalekit automatically handles organization switching during the authentication flow:

1. Users click **Sign In** on your application.
2. Your application redirects users to Scalekit's sign-in page.
3. Users authenticate using one of the available sign-in methods.
4. Scalekit displays a list of organizations that users belong to.
5. Users select the organization they want to sign in to.
6. Users are redirected to the organization's workspace and signed in.
**Note:** For organizations with Single Sign-On (SSO) enabled on a verified domain, the sign-in flow is automated. When a user enters their work email address, Scalekit redirects them to their organization's identity provider to sign in. The organization selection step is skipped.

Scalekit provides built-in support for organization switching through automatic organization detection, a hosted organization switcher UI, and secure session management. Each organization maintains its own authentication context and policies.

## Control organization switching behavior

You can customize the organization switcher's behavior by adding query parameters when generating the authorization URL. These parameters give you precise control over how users navigate between organizations.

### Display organization switcher

Add the `prompt: 'select_account'` parameter when generating the authorization URL. This forces Scalekit to display a list of organizations the user belongs to, even if they're already signed in.

```javascript title="Express.js" wrap "authorizationUrl" ins={4}
    // Use case: Show organization switcher after user authentication
    const redirectUri = 'http://localhost:3000/api/callback';
    const options = {
      scopes: ['openid', 'profile', 'email', 'offline_access'],
      prompt: 'select_account'
    };

    const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options);

    res.redirect(authorizationUrl);
    ```
  ```python title="Flask" wrap "authorizationUrl" ins={6}
    # Use case: Show organization switcher after user authentication
    from scalekit import AuthorizationUrlOptions

    redirect_uri = 'http://localhost:3000/api/callback'
    options = AuthorizationUrlOptions()
    options.scopes = ['openid', 'profile', 'email', 'offline_access']
    options.prompt = 'select_account'

    authorization_url = scalekit.get_authorization_url(redirect_uri, options)
    return redirect(authorization_url)
    ```
  ```go title="Gin" wrap "authorizationUrl" ins={5}
    // Use case: Show organization switcher after user authentication
    redirectUri := "http://localhost:3000/api/callback"
    options := scalekit.AuthorizationUrlOptions{
        Scopes: []string{"openid", "profile", "email", "offline_access"},
        Prompt: "select_account",
    }

    authorizationUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options)
    if err != nil {
        // handle error appropriately
        panic(err)
    }

    c.Redirect(http.StatusFound, authorizationUrl.String())
    ```
  ```java title="Spring" wrap "authorizationUrl" ins={8}
    // Use case: Show organization switcher after user authentication
    import com.scalekit.internal.http.AuthorizationUrlOptions;
    import java.net.URL;
    import java.util.Arrays;

    String redirectUri = "http://localhost:3000/api/callback";
    AuthorizationUrlOptions options = new AuthorizationUrlOptions();
    options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access"));
    options.setPrompt("select_account");

    URL authorizationUrl = scalekit.authentication().getAuthorizationUrl(redirectUri, options);
    ```
  This displays the organization switcher UI where users can choose which organization to access.

### Switch users directly to a specific organization

To bypass the organization switcher and directly authenticate users into a specific organization, include both the `prompt: 'select_account'` parameter and the `organizationId` parameter:

```javascript title="Express.js" wrap "authorizationUrl" ins={4,5}
    // Use case: Directly route users to a specific organization
    const redirectUri = 'http://localhost:3000/api/callback';
    const options = {
      scopes: ['openid', 'profile', 'email', 'offline_access'],
      prompt: 'select_account',
      organizationId: 'org_1233434'
    };

    const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options);

    res.redirect(authorizationUrl);
    ```
  ```python title="Flask" wrap "authorizationUrl" ins={6,7}
    # Use case: Directly route users to a specific organization
    from scalekit import AuthorizationUrlOptions

    redirect_uri = 'http://localhost:3000/api/callback'
    options = AuthorizationUrlOptions()
    options.scopes = ['openid', 'profile', 'email', 'offline_access']
    options.prompt = 'select_account'
    options.organization_id = 'org_1233434'

    authorization_url = scalekit.get_authorization_url(redirect_uri, options)
    return redirect(authorization_url)
    ```
  ```go title="Gin" wrap "authorizationUrl" ins={4,5}
    // Use case: Directly route users to a specific organization
    redirectUri := "http://localhost:3000/api/callback"
    options := scalekit.AuthorizationUrlOptions{
        Scopes: []string{"openid", "profile", "email", "offline_access"},
        Prompt: "select_account",
        OrganizationId: "org_1233434",
    }

    authorizationUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options)
    if err != nil {
        // handle error appropriately
        panic(err)
    }

    c.Redirect(http.StatusFound, authorizationUrl.String())
    ```
  ```java title="Spring" wrap "authorizationUrl" ins={8,9}
    // Use case: Directly route users to a specific organization
    import com.scalekit.internal.http.AuthorizationUrlOptions;
    import java.net.URL;
    import java.util.Arrays;

    String redirectUri = "http://localhost:3000/api/callback";
    AuthorizationUrlOptions options = new AuthorizationUrlOptions();
    options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access"));
    options.setPrompt("select_account");
    options.setOrganizationId("org_1233434");

    URL authorizationUrl = scalekit.authentication().getAuthorizationUrl(redirectUri, options);
    ```
  When you include both parameters, Scalekit will:
- **If the user is already authenticated**: Directly sign them into the specified organization
- **If the user needs to authenticate**: First authenticate the user, then sign them into the specified organization

## Organization switching parameters

Use these parameters to control the organization switching behavior:

| Parameter | Description | Example |
|-----------|-------------|---------|
| `prompt=select_account` | Shows the organization switcher UI | Forces organization selection even for authenticated users |
| `prompt=select_account&organizationId=org_123` | Direct organization access | Bypasses switcher and authenticates directly into the specified organization |
**Tip:** The `organizationId` parameter works only when combined with `prompt=select_account`. Using `organizationId` alone will not have the desired effect.
{/* 
## Build your own organization switcher API

If you want more control over the organization switching experience, you can build your own organization switcher inside your application. This gives you full flexibility to design the UI and routing logic that matches your application's design system.

### Your organization switcher flow

When building your own organization switcher, follow this typical flow:

1. User logs in and gets authenticated through Scalekit.
2. Your application queries Scalekit APIs to fetch organizations and domains the user has access to.
3. You render your own organization selector UI with the fetched organization data.
4. Once an organization is selected, your application continues with that organization context.

### Fetch user's organizations

To build your own organization switcher, you need to retrieve the organizations a user belongs to. Use the [User sessions API](https://docs.scalekit.com/apis/#tag/sessions/GET/api/v1/sessions/{session_id}) to get the authenticated user's session information, which includes the `authenticated_organizations` field.

```javascript title="Fetch user's organizations"
    // Use case: Get user's organizations for your own organization switcher UI
    const session = await scalekit.session.getSession(sessionId);

    // Check authenticated_organizations in the response
    const organizations = session.authenticated_organizations || [];

    // Render your organization switcher UI with organizations
    res.json({ organizations });
    ```
  ```python title="Fetch user's organizations"
    # Use case: Get user's organizations for your own organization switcher UI
    session = scalekit_client.session.get_session(session_id)

    # Check authenticated_organizations in the response
    organizations = session.get('authenticated_organizations', [])

    # Render your organization switcher UI with organizations
    return jsonify({'organizations': organizations})
    ```
  ```go title="Fetch user's organizations"
    // Use case: Get user's organizations for your own organization switcher UI
    session, err := scalekitClient.Session().GetSession(ctx, sessionId)
    if err != nil {
        // handle error appropriately
        return err
    }

    // Check authenticated_organizations in the response
    organizations := session.AuthenticatedOrganizations

    // Render your organization switcher UI with organizations
    c.JSON(http.StatusOK, gin.H{"organizations": organizations})
    ```
  ```java title="Fetch user's organizations"
    // Use case: Get user's organizations for your own organization switcher UI
    Session session = scalekitClient.sessions().getSession(sessionId);

    // Check authenticated_organizations in the response
    List<Organization> organizations = session.getAuthenticatedOrganizations();

    // Render your organization switcher UI with organizations
    return ResponseEntity.ok(Map.of("organizations", organizations));
    ```
  ### Fetch organization domains

You can also use the [Domains API](https://docs.scalekit.com/apis/#tag/domains) to get domain information for organizations. This helps you display additional context in your organization switcher, such as which domains are associated with each organization.
**Note:** When building your own organization switcher, you own the UI and routing logic. This gives you full flexibility but requires you to handle organization selection, session management, and routing within your application. */}