Skip to main content

Overview

The Workspaces API allows organizers to create and manage their organization workspaces, invite team members, configure settings, and control access permissions.

Create Workspace

Create a new workspace during organizer onboarding.
import { createWorkspace } from '@/app/actions/workspace';

const formData = new FormData();
formData.append('name', 'Tech Events Inc');
formData.append('description', 'We organize technology conferences');
formData.append('website', 'https://techevents.com');
formData.append('phone', '+254712345678');

const result = await createWorkspace(null, formData);

Parameters

name
string
required
Workspace name (1-255 characters)
description
string
Description of your organization
website
string
Organization website URL (must be valid URL)
phone
string
Contact phone number (max 50 characters)
social_x
string
X (Twitter) profile URL
social_facebook
string
Facebook profile URL
social_linkedin
string
LinkedIn profile URL
social_instagram
string
Instagram profile URL
social_github
string
GitHub profile URL
Workspace logo image file

Response

success
boolean
Whether workspace was created successfully
workspaceId
string
ID of the created workspace
error
string
Error message if creation failed

Workspace Creation Process

1

Permission Check

Only users with platform_role: "organizer" can create workspaces.
2

Validation

System validates:
  • Name is required and within length limits
  • URLs are valid (if provided)
  • User doesn’t already have a workspace
3

Invite Code Generation

A unique invite code is generated for the workspace:
const inviteCode = generateNanoId() + generateNanoId();
4

Creator Added as Admin

The workspace creator is automatically added as an admin member:
await db.insert(tables.workspace_members).values({
  user_id: user.id,
  workspace_id: workspace.id,
  role: WorkspaceRole.ADMIN
});
One Workspace Per Organizer: Each organizer account can only create one workspace. To manage multiple organizations, invite team members with appropriate roles.

Get Workspace Details

Retrieve workspace information with access check.
import { getWorkspace } from '@/app/actions/workspace';

const workspace = await getWorkspace('wks_abc123');

Server Action (DAL)

Alternatively, use the cached DAL function:
import { getWorkspaceWithAccess } from '@/dal/workspace';

const { workspace, role, isOwner } = await getWorkspaceWithAccess('wks_abc123');

Response

workspace
object
Workspace details including:
  • id - Workspace identifier
  • name - Workspace name
  • description - Organization description
  • image_url - Logo URL
  • invite_code - Invite code for new members
  • website - Organization website
  • Social media links
  • user_id - Workspace owner ID
  • created_at - Creation timestamp
role
WorkspaceRole
User’s role in the workspace: admin, moderator, or member
isOwner
boolean
True if user is the workspace owner

Invite Members

Invite team members to join your workspace.
import { inviteWorkspaceMembers } from '@/app/actions/workspace';
import { WorkspaceRole } from '@/lib/db/schema/enums';

const result = await inviteWorkspaceMembers(
  'wks_abc123',
  ['[email protected]', '[email protected]'],
  WorkspaceRole.MODERATOR
);

API Route

You can also use the API endpoint:
POST /api/workspace/invite
Request Body:
{
  "emails": ["[email protected]", "[email protected]"],
  "workspaceId": "wks_abc123",
  "workspaceName": "Tech Events Inc",
  "invitedByName": "John Doe",
  "invitedByEmail": "[email protected]",
  "role": "moderator",
  "inviteCode": "unique_invite_code"
}

Parameters

workspaceId
string
required
ID of the workspace
emails
string[]
required
Array of email addresses to invite
role
WorkspaceRole
default:"member"
Role to assign to invited members:
  • admin - Full workspace management
  • moderator - Can create and manage events
  • member - View-only access

Response

success
boolean
Whether invitations were sent
results
array
Array of invitation results, each containing:
  • email - Email address
  • status - sent, already_member, or failed

Invitation Flow

1

Permission Check

Only workspace admins can invite members.
2

Membership Verification

System checks if users are already members:
const existingMember = await db.query.workspace_members.findFirst({
  where: and(
    eq(tables.workspace_members.workspace_id, workspaceId),
    eq(tables.workspace_members.user_id, existingUser.id)
  )
});

if (existingMember) {
  return { status: 'already_member' };
}
3

Invitation Storage

Invitations are stored in the database with:
  • Unique token
  • Expiration date (7 days)
  • Role assignment
4

Email Notification

Invited users receive an email with:
  • Workspace information
  • Invite link
  • Role details
  • Inviter information
Emails are sent in parallel for better performance.

Join Workspace

Join a workspace using an invite code.
import { joinWorkspace } from '@/app/actions/workspace';

const formData = new FormData();
formData.append('inviteCode', 'unique_invite_code');

const result = await joinWorkspace(null, formData);

Parameters

inviteCode
string
required
Unique workspace invite code

Response

success
boolean
Whether join was successful
workspaceId
string
ID of the workspace joined
workspaceName
string
Name of the workspace
error
string
Error message if join failed

Workspace Roles

Workspaces support three role levels:
Full Management AccessAdmins can:
  • Create, edit, and delete events
  • Invite and remove members
  • Update workspace settings
  • Manage team member roles
  • Access all analytics and reports
  • Configure payment settings
role: WorkspaceRole.ADMIN

Role Hierarchy

const roleHierarchy = {
  member: 1,
  moderator: 2,
  admin: 3
};

// Check if user has required role or higher
if (roleHierarchy[userRole] >= roleHierarchy[requiredRole]) {
  // Allow access
}

Get Workspace Members

Retrieve list of all workspace members.
import { getWorkspaceMembers } from '@/app/actions/workspace';

const members = await getWorkspaceMembers('wks_abc123');

Response

Array of member objects:
id
string
Member record ID
userId
string
User account ID
name
string
User’s display name
email
string
User’s email address
avatar
string | null
User’s avatar URL
role
WorkspaceRole
Member’s role in the workspace
joinedDate
Date
Date member joined the workspace
isYou
boolean
True if this is the current user

Update Member Role

Change a member’s role in the workspace.
import { updateMemberRole } from '@/app/actions/workspace';
import { WorkspaceRole } from '@/lib/db/schema/enums';

const formData = new FormData();
formData.append('memberId', 'mbr_abc123');
formData.append('workspaceId', 'wks_xyz789');
formData.append('role', WorkspaceRole.ADMIN);

const result = await updateMemberRole(null, formData);

Restrictions

  • Only workspace admins can update roles
  • Cannot change the workspace owner’s role
  • Must provide valid role from WorkspaceRole enum

Remove Member

Remove a member from the workspace.
import { removeMember } from '@/app/actions/workspace';

const formData = new FormData();
formData.append('memberId', 'mbr_abc123');
formData.append('workspaceId', 'wks_xyz789');

const result = await removeMember(null, formData);

Restrictions

  • Only workspace admins can remove members
  • Cannot remove the workspace owner
  • Member is immediately removed from workspace

Workspace Settings

Update various workspace settings.

Update Workspace Name

import { updateWorkspaceName } from '@/app/actions/workspace';

const result = await updateWorkspaceName(
  'wks_abc123',
  'New Organization Name'
);
import { updateWorkspaceLogo } from '@/app/actions/workspace';

const result = await updateWorkspaceLogo(
  'wks_abc123',
  'https://storage.example.com/logo.png'
);
Image Size Limit: Logo images must be under 2MB. The system stores base64-encoded images directly in the database.
import { updateWorkspaceSocialLinks } from '@/app/actions/workspace';

const result = await updateWorkspaceSocialLinks('wks_abc123', {
  website: 'https://techevents.com',
  social_x: 'https://x.com/techevents',
  social_linkedin: 'https://linkedin.com/company/techevents',
  social_instagram: 'https://instagram.com/techevents',
  social_facebook: 'https://facebook.com/techevents',
  social_github: 'https://github.com/techevents'
});
All URLs are validated before saving:
.refine(
  (val) => {
    if (!val || val === "") return true;
    try {
      new URL(val);
      return true;
    } catch {
      return false;
    }
  },
  { message: "Invalid URL" }
)

Transfer Workspace Ownership

Transfer workspace ownership to another member.
import { transferWorkspace } from '@/app/actions/workspace';

const result = await transferWorkspace(
  'wks_abc123',
  '[email protected]',
  'transfer', // Confirmation word
  '2fa_token' // Required if 2FA enabled
);

Parameters

workspaceId
string
required
ID of the workspace to transfer
newOwnerEmail
string
required
Email of the new owner (must be a workspace member)
confirmationWord
string
required
Must type exactly “TRANSFER” to confirm
verificationToken
string
2FA token (required if 2FA is enabled on account)

Transfer Process

1

Verification

System verifies:
  • User is the workspace owner
  • New owner exists and is a member
  • Confirmation word is correct
  • 2FA token is valid (if enabled)
2

Ownership Transfer

await db.update(tables.workspace).set({
  user_id: newOwner.id
});
3

Role Updates

  • Previous owner becomes a MEMBER
  • New owner becomes ADMIN (if not already)
4

Email Notification

New owner receives confirmation email with full workspace access details.
Irreversible Action: Workspace transfer cannot be undone. The new owner gains full control including the ability to remove the previous owner.

Delete Workspace

Permanently delete a workspace.
import { deleteWorkspace } from '@/app/actions/workspace';

const result = await deleteWorkspace(
  'wks_abc123',
  'delete', // Confirmation word
  '2fa_token' // Required if 2FA enabled
);

Parameters

workspaceId
string
required
ID of the workspace to delete
confirmationWord
string
required
Must type exactly “DELETE” to confirm
verificationToken
string
2FA token (required if 2FA is enabled)

Deletion Process

1

Verification

  • Only workspace owner can delete
  • Confirmation word must be exact
  • 2FA verification (if enabled)
2

Member Cleanup

All workspace members are removed:
await db.delete(tables.workspace_members)
  .where(eq(tables.workspace_members.workspace_id, workspaceId));
3

Workspace Deletion

The workspace record is permanently deleted.
4

Redirect

  • If user has other workspaces: redirect to dashboard
  • If no workspaces remain: redirect to no-workspace page
Permanent Deletion: Deleting a workspace removes all associated data including events, tickets, and member records. This action cannot be undone.

Get Pending Invites

View pending workspace invitations.
import { getPendingInvites } from '@/app/actions/workspace';

const result = await getPendingInvites('wks_abc123');

Response

success
boolean
Whether the query was successful
invites
array
Array of pending invitations, each containing:
  • id - Invitation ID
  • email - Invited email address
  • role - Role to be assigned
  • sentAt - Invitation timestamp
Expired invitations (>7 days old) are automatically filtered out.

Export Members CSV

Export workspace members as CSV file.
import { exportMembersCSV } from '@/app/actions/workspace';

const result = await exportMembersCSV('wks_abc123');

if (result.success) {
  // Download or save result.csv
  const blob = new Blob([result.csv], { type: 'text/csv' });
  const url = URL.createObjectURL(blob);
  // Trigger download
}

CSV Format

Name,Email,Role,Joined Date
"John Doe","[email protected]","ADMIN","1/15/2024"
"Jane Smith","[email protected]","MODERATOR","2/1/2024"
Admin Only: Only workspace admins can export member data.

Error Handling

Common workspace errors:
ErrorCauseSolution
"Only organizers can create workspaces"User is an attendeeSwitch to organizer account
"Workspace not found"Invalid workspace IDVerify workspace exists
"Only workspace admins can invite members"Insufficient permissionsRequest admin access
"Invalid invite code"Code is wrong or expiredRequest new invite
"You are already a member of this workspace"Duplicate join attemptAlready have access
"Cannot remove workspace owner"Attempted to remove ownerTransfer ownership first
"Cannot change workspace owner's role"Attempted role change on ownerTransfer ownership first

Complete Example

Complete workspace setup with team:
import { 
  createWorkspace, 
  inviteWorkspaceMembers,
  updateWorkspaceSocialLinks 
} from '@/app/actions/workspace';
import { WorkspaceRole } from '@/lib/db/schema/enums';

async function setupWorkspace() {
  // 1. Create workspace
  const formData = new FormData();
  formData.append('name', 'Tech Events Inc');
  formData.append('description', 'Premium technology conferences');
  formData.append('website', 'https://techevents.com');
  formData.append('phone', '+254712345678');
  
  const createResult = await createWorkspace(null, formData);
  
  if (!createResult.success) {
    console.error('Failed to create workspace:', createResult.error);
    return;
  }
  
  const workspaceId = createResult.workspaceId!;
  console.log('Workspace created:', workspaceId);
  
  // 2. Add social links
  await updateWorkspaceSocialLinks(workspaceId, {
    social_x: 'https://x.com/techevents',
    social_linkedin: 'https://linkedin.com/company/techevents',
    social_github: 'https://github.com/techevents'
  });
  
  // 3. Invite team members
  const inviteResult = await inviteWorkspaceMembers(
    workspaceId,
    [
      '[email protected]',
      '[email protected]'
    ],
    WorkspaceRole.MODERATOR
  );
  
  if (inviteResult.success) {
    console.log('Invitations sent:', inviteResult.results);
  }
  
  console.log('Workspace setup complete!');
  return workspaceId;
}

Next Steps

Events API

Create events in your workspace

Users API

Manage user accounts

Team Collaboration

Learn about team features

Workspace Settings

Configure workspace options

Build docs developers (and LLMs) love