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
Workspace name (1-255 characters)
Description of your organization
Organization website URL (must be valid URL)
Contact phone number (max 50 characters)
Workspace logo image file
Response
Whether workspace was created successfully
ID of the created workspace
Error message if creation failed
Workspace Creation Process
Permission Check
Only users with platform_role: "organizer" can create workspaces.
Validation
System validates:
Name is required and within length limits
URLs are valid (if provided)
User doesn’t already have a workspace
Invite Code Generation
A unique invite code is generated for the workspace: const inviteCode = generateNanoId () + generateNanoId ();
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 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
User’s role in the workspace: admin, moderator, or member
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:
Parameters
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
Whether invitations were sent
Array of invitation results, each containing:
email - Email address
status - sent, already_member, or failed
Invitation Flow
Permission Check
Only workspace admins can invite members.
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' };
}
Invitation Storage
Invitations are stored in the database with:
Unique token
Expiration date (7 days)
Role assignment
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
Unique workspace invite code
Response
Whether join was successful
ID of the workspace joined
Error message if join failed
Workspace Roles
Workspaces support three role levels:
Full Management Access Admins 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
Event Management Moderators can:
Create and edit events
View attendee lists
Scan tickets at events
Access event analytics
Cannot invite members or change settings
role : WorkspaceRole . MODERATOR
View-Only Access Members can:
View workspace events
See team member list
Cannot create events or invite others
role : WorkspaceRole . MEMBER
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:
Member’s role in the workspace
Date member joined the workspace
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'
);
Update Workspace Logo
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.
Update Social Links
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
ID of the workspace to transfer
Email of the new owner (must be a workspace member)
Must type exactly “TRANSFER” to confirm
2FA token (required if 2FA is enabled on account)
Transfer Process
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)
Ownership Transfer
await db . update ( tables . workspace ). set ({
user_id: newOwner . id
});
Role Updates
Previous owner becomes a MEMBER
New owner becomes ADMIN (if not already)
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
ID of the workspace to delete
Must type exactly “DELETE” to confirm
2FA token (required if 2FA is enabled)
Deletion Process
Verification
Only workspace owner can delete
Confirmation word must be exact
2FA verification (if enabled)
Member Cleanup
All workspace members are removed: await db . delete ( tables . workspace_members )
. where ( eq ( tables . workspace_members . workspace_id , workspaceId ));
Workspace Deletion
The workspace record is permanently deleted.
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
Whether the query was successful
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
}
Admin Only: Only workspace admins can export member data.
Error Handling
Common workspace errors:
Error Cause Solution "Only organizers can create workspaces"User is an attendee Switch to organizer account "Workspace not found"Invalid workspace ID Verify workspace exists "Only workspace admins can invite members"Insufficient permissions Request admin access "Invalid invite code"Code is wrong or expired Request new invite "You are already a member of this workspace"Duplicate join attempt Already have access "Cannot remove workspace owner"Attempted to remove owner Transfer ownership first "Cannot change workspace owner's role"Attempted role change on owner Transfer 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