Default Workspace and Membership
Overview
This flow covers how a SYSTEM user discovers accessible workspaces, creates one when needed, and manages the invitation and role pieces that define membership. The important implementation detail is that user-scoped and admin-style workspace endpoints live under different URL families.
Prerequisites
Authorization: Bearer <accessToken>X-PORTAL-ACCESS-CODE: <system-portal-code>- clarity on whether the caller is acting on their own workspace or administering a shared one
- workspace permissions for invitation and role management where required
Shared Headers
X-PORTAL-ACCESS-CODE: <system-portal-code>
Authorization: Bearer <accessToken>
Content-Type: application/jsonStep-by-Step Flow
1. List workspaces available to the current user
API endpoint: GET /web/v1/partner/workspaces/mine This is the starting point for workspace routing after login.
curl 'https://api.example.com/web/v1/partner/workspaces/mine' \
-H 'X-PORTAL-ACCESS-CODE: <system-portal-code>' \
-H 'Authorization: Bearer <accessToken>'{"code":"2000","message":"SUCCESS","data":[{"bizId":"WS_INVITE_TEST_001","workspaceName":"Primary Workspace","workspaceTimezone":"UTC","workspaceStatus":{"code":"ACTIVE","value":10010701,"name":"ACTIVE"}}]}2. Create a workspace when none exist
API endpoint: POST /web/v1/workspaces/self This creates a workspace owned by the current user and assigns the owner role automatically.
curl -X POST 'https://api.example.com/web/v1/workspaces/self' \
-H 'X-PORTAL-ACCESS-CODE: <system-portal-code>' \
-H 'Authorization: Bearer <accessToken>' \
-H 'Content-Type: application/json' \
-d '{"workspaceName":"My Payment Workspace","workspaceTimezone":"America/Los_Angeles","extraData":"{\"source\":\"system-portal\"}"}'{"code":"2001","message":"CREATED","data":{"bizId":"ws_abc123def456","workspaceName":"My Payment Workspace","workspaceTimezone":"America/Los_Angeles","workspaceKind":{"code":"LIVE","value":10010801,"name":"LIVE"}}}3. Set the default workspace
API endpoint: POST /web/v1/partner/workspaces/{workspaceBizId}/default Mark one accessible workspace as the default landing target.
curl -X POST 'https://api.example.com/web/v1/partner/workspaces/WS_INVITE_TEST_001/default' \
-H 'X-PORTAL-ACCESS-CODE: <system-portal-code>' \
-H 'Authorization: Bearer <accessToken>'{"code":"2000","message":"SUCCESS","data":{"bizId":"WS_INVITE_TEST_001","workspaceName":"Primary Workspace","workspaceStatus":{"code":"ACTIVE","value":10010701,"name":"ACTIVE"}}}4. Read or create assignable roles
API endpoints: GET /web/v1/workspaces/{workspaceId}/roles, POST /web/v1/workspaces/{workspaceId}/roles List roles before creating new custom roles so the UI can avoid duplicates.
curl 'https://api.example.com/web/v1/workspaces/WS_ROLE_TEST_001/roles' \
-H 'X-PORTAL-ACCESS-CODE: <system-portal-code>' \
-H 'Authorization: Bearer <accessToken>'{"code":"2000","message":"SUCCESS","data":[{"bizId":"ROLE_OWNER_TEST_001","roleName":"Owner","roleType":{"code":"OWNER","value":10010901,"name":"OWNER"}},{"bizId":"ROLE_CUSTOM_TEST_001","roleName":"Member","roleType":{"code":"CUSTOM","value":10010902,"name":"CUSTOM"}}]}5. Invite a new member
API endpoint: POST /web/v1/workspaces/{workspaceBizId}/invitations This creates the pending membership record that the invitee later accepts.
curl -X POST 'https://api.example.com/web/v1/workspaces/WS_INVITE_TEST_001/invitations' \
-H 'X-PORTAL-ACCESS-CODE: <system-portal-code>' \
-H 'Authorization: Bearer <accessToken>' \
-H 'Content-Type: application/json' \
-d '{"inviteeEmail":"invitee@example.com","message":"Welcome to our workspace","expirationDays":7}'{"code":"2001","message":"CREATED","data":{"bizId":"inv_abc123def456","workspaceBizId":"WS_INVITE_TEST_001","invitationStatus":{"code":"PENDING","value":10011001,"name":"PENDING"},"canAccept":true}}6. Change the role of an existing member
API endpoint: POST /web/v1/workspaces/{workspaceId}/members/role/change Update the target member's assigned role after they join.
curl -X POST 'https://api.example.com/web/v1/workspaces/WS_ROLE_TEST_001/members/role/change' \
-H 'X-PORTAL-ACCESS-CODE: <system-portal-code>' \
-H 'Authorization: Bearer <accessToken>' \
-H 'Content-Type: application/json' \
-d '{"accountId":"ACC_ROLE_MEMBER_001","workspaceRoleBizId":"ROLE_CUSTOM_TEST_001"}'{"code":"2004","message":"NO_CONTENT","data":null}Decision Points
- if the user has zero workspaces, create or invitation acceptance becomes the next step
- if multiple workspaces exist, setting a default reduces future routing friction
- if only built-in roles are needed, skip custom-role creation
- if the invitee is not yet registered, keep the invitation pending until onboarding completes
Error Handling
WORKSPACE.ALREADY_OWNS_WORKSPACEmeans the account already owns a workspaceWORKSPACE.ROLE_NAME_EXISTSmeans the requested custom role name is already in use- duplicate invitation conflicts should surface as a targeted retry or replace action
4010usually means the token expired or the caller lacks workspace permission