Organizations

Enable B2B features with multi-user organizations that share a single subscription.

How Organizations Work

Organizations allow multiple customers (users) to share a single subscription:

  • Shared subscription — One subscription covers all org members
  • Role-based access — Owner, Admin, and Member roles
  • Invite flow — Invite users via email with magic link
  • Org-scoped entitlements — Entitlement checks use the org's subscription

Enable organizations: Go to your app settings and toggle "Enable Organizations" to activate B2B features.

Create Organization

Create an organization. The creating customer becomes the owner.

Customer-Initiated (from your app)

typescript
// Customer creates their own organization
const org = await stackbe.organizations.create({
  name: 'Acme Inc',
  slug: 'acme-inc',  // Optional, auto-generated if not provided
}, {
  sessionToken: customerSessionToken,  // Customer's session
});

console.log(org);
// {
//   id: 'org_xyz789',
//   name: 'Acme Inc',
//   slug: 'acme-inc',
//   createdAt: '2025-01-15T10:30:00Z'
// }

Server-Side (with API key)

typescript
// Create org on behalf of a customer (e.g., during onboarding)
const org = await stackbe.organizations.create({
  name: 'Acme Inc',
  ownerId: 'cust_abc123',  // Customer who will own the org
});

Invite Members

Invite users to join an organization. They receive a magic link email to accept.

typescript
// Invite a new member (owners and admins can invite)
await stackbe.organizations.inviteMember(orgId, {
  email: 'colleague@example.com',
  role: 'member',  // 'owner' | 'admin' | 'member'
}, {
  sessionToken: adminSessionToken,
});

// The invitee receives an email with a magic link
// Clicking the link creates their account (if new) and adds them to the org

Server-Side Invite

typescript
// Add member directly (skip invite email)
await stackbe.organizations.addMember(orgId, {
  customerId: 'cust_xyz789',
  role: 'admin',
});

List Members

Get all members of an organization with their roles.

typescript
const members = await stackbe.organizations.listMembers(orgId);

console.log(members);
// [
//   { customerId: 'cust_abc123', email: 'owner@acme.com', role: 'owner' },
//   { customerId: 'cust_def456', email: 'admin@acme.com', role: 'admin' },
//   { customerId: 'cust_ghi789', email: 'member@acme.com', role: 'member' },
// ]

Organization Context

When a customer belongs to multiple organizations, they can switch context. The session token includes the current org.

typescript
// List customer's organizations
const orgs = await stackbe.organizations.list({
  sessionToken: customerSessionToken,
});

// Switch to a different organization
const newSession = await stackbe.auth.switchOrganization(
  sessionToken,
  'org_xyz789'
);

// New session token includes org context
// { organizationId: 'org_xyz789', orgRole: 'admin' }

// All subsequent entitlement checks use the org's subscription
const entitlements = await stackbe.entitlements.get(customerId);
// Returns entitlements from org's subscription, not individual's

Auto-Select Single Org

If a customer belongs to exactly one organization, they're automatically placed in that org's context on login. No manual switch needed.

Roles & Permissions

Owner

  • Full control over the organization
  • Can manage billing and subscription
  • Can invite/remove any member
  • Can transfer ownership
  • Can delete the organization

Admin

  • Can invite/remove members (except owner)
  • Can manage org settings
  • Cannot change billing

Member

  • Access to org's features based on subscription
  • Cannot invite or manage members
  • Can leave the organization

Billing for Organizations

Create checkout sessions for organizations to subscribe them to a plan.

typescript
// Checkout for an organization (owner only)
const { url } = await stackbe.checkout.createSession({
  organizationId: 'org_xyz789',
  planId: 'plan_team',
  successUrl: 'https://yourapp.com/org/settings?upgraded=true',
  cancelUrl: 'https://yourapp.com/org/settings',
});

redirect(url);

UI Pattern: Org Switcher

Build an organization switcher for customers with multiple orgs.

typescript
// React component example
function OrgSwitcher() {
  const { session, switchOrg } = useStackBE();
  const [orgs, setOrgs] = useState([]);

  useEffect(() => {
    stackbe.organizations.list({ sessionToken: session.token })
      .then(setOrgs);
  }, []);

  const handleSwitch = async (orgId) => {
    const newSession = await switchOrg(orgId);
    // Update your app's session state
    // Refresh data that depends on org context
  };

  return (
    <select
      value={session.organizationId || 'personal'}
      onChange={(e) => handleSwitch(e.target.value)}
    >
      <option value="personal">Personal Account</option>
      {orgs.map(org => (
        <option key={org.id} value={org.id}>
          {org.name}
        </option>
      ))}
    </select>
  );
}

Next Steps