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)
// 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)
// 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.
// 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 orgServer-Side Invite
// 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.
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.
// 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'sAuto-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.
// 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.
// 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>
);
}