Skip to main content
The workspace actions endpoint is a single POST route that accepts a discriminated action body. Every mutating operation on organizations — creating one, updating its settings or branding, managing locations, roles, members, billing, and even deleting the org — is dispatched through this one endpoint. The action field in the request body determines which operation runs and which additional fields are required. All requests require a valid Bearer token. Most actions that target an existing organization also require your role to have the corresponding permission. See Org permission model below.

Workspace actions endpoint

POST /v1/workspace/actions

Request headers

Authorization
string
required
Bearer token from your Clerk session. Example: Bearer eyJhbGc...
Content-Type
string
required
Must be application/json.

Request body

action
string
required
The action to perform. Must be one of the action type strings listed in the sections below.
Additional fields depend on the action value. Each action is documented in its own section below.

Response

On success, returns { "ok": true } plus any action-specific fields (e.g., createdOrgId). On failure, returns HTTP 400 with an error body:
{ "error": "Human-readable error message." }
Validation failures also include a structured issues field:
{
  "error": "Invalid body.",
  "issues": { ... }
}

Create organization

action: createOrganization Creates a new organization and sets it as the caller’s active organization. The caller is automatically assigned the built-in owner role and a free-tier billing account is provisioned.

Body fields

action
string
required
"createOrganization"
name
string
required
Organization display name. 1–120 characters.
slug
string
URL-safe slug for the organization. Lowercase alphanumeric with hyphens; 2–48 characters; must start and end with an alphanumeric character. If omitted, a slug is auto-generated from name. Must be unique across all organizations.

Response fields

ok
boolean
required
true on success.
createdOrgId
string
required
ID of the newly created organization.

Example

curl --request POST \
  --url https://your-api.example.com/v1/workspace/actions \
  --header 'Authorization: Bearer <your-session-token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "action": "createOrganization",
    "name": "Acme Auto Finance",
    "slug": "acme-auto-finance"
  }'

Set active organization

action: setActiveOrganization Sets the active organization for your user session. You must already be an active member of the target organization. The touchActiveOrganizationFromNavigation action is an alias with identical behavior, used internally by the navigation shell.

Body fields

action
string
required
"setActiveOrganization" or "touchActiveOrganizationFromNavigation"
orgId
string
required
ID of the organization to set as active. Must be an org you are an active member of.

Example

curl --request POST \
  --url https://your-api.example.com/v1/workspace/actions \
  --header 'Authorization: Bearer <your-session-token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "action": "setActiveOrganization",
    "orgId": "org_01j9z8aabbccdd"
  }'

Update organization settings

action: updateOrganizationSettings Updates the display name and slug for an existing organization. Requires the orgSettings permission.
Changing the slug affects any external links or integrations that reference the organization by slug. Confirm downstream dependencies before updating.

Body fields

action
string
required
"updateOrganizationSettings"
orgId
string
required
ID of the organization to update.
name
string
required
New display name. 1–120 characters.
slug
string
required
New slug. Lowercase alphanumeric with hyphens; 2–48 characters; must start and end with an alphanumeric character. Must be unique across all organizations.

Update organization branding

action: updateOrganizationBrand Updates the custom brand name, logo URL, and primary color for an organization. Requires the brand permission. All fields are optional; pass null to clear a value.

Body fields

action
string
required
"updateOrganizationBrand"
orgId
string
required
ID of the organization to update.
brandName
string or null
Custom brand display name. Maximum 120 characters. Pass null to clear.
brandLogoUrl
string or null
URL to the organization logo. Maximum 2000 characters. Pass null to clear.
brandPrimaryHex
string or null
Primary brand color as a #RRGGBB hex string (e.g. "#1A56DB"). Maximum 7 characters. Pass null to clear.

Create location

action: createOrgLocation Adds a new location to the organization. Locations are appended at the end of the existing sort order. Requires the locations permission.

Body fields

action
string
required
"createOrgLocation"
orgId
string
required
ID of the organization.
name
string
required
Location display name. 1–120 characters.
addressLine1
string or null
Street address. Maximum 200 characters.
city
string or null
City. Maximum 80 characters.
region
string or null
State, province, or region. Maximum 80 characters.
postalCode
string or null
Postal code. Maximum 20 characters.
countryCode
string or null
ISO 3166-1 alpha-2 country code (e.g. "US"). Stored in uppercase. Maximum 2 characters.
phone
string or null
Phone number. Maximum 40 characters.

Update location

action: updateOrgLocation Updates an existing location. Requires the locations permission.

Body fields

action
string
required
"updateOrgLocation"
orgId
string
required
ID of the organization.
locationId
string
required
ID of the location to update. Must belong to the specified organization.
name
string
required
Updated location name. 1–120 characters.
addressLine1
string or null
Updated street address. Maximum 200 characters.
city
string or null
Updated city. Maximum 80 characters.
region
string or null
Updated region. Maximum 80 characters.
postalCode
string or null
Updated postal code. Maximum 20 characters.
countryCode
string or null
Updated country code. Stored in uppercase. Maximum 2 characters.
phone
string or null
Updated phone number. Maximum 40 characters.

Delete location

action: deleteOrgLocation Permanently removes a location from the organization. Requires the locations permission.

Body fields

action
string
required
"deleteOrgLocation"
orgId
string
required
ID of the organization.
locationId
string
required
ID of the location to delete. Must belong to the specified organization.

Create role

action: createOrgRole Creates a new custom role for the organization with a defined permission set. Requires the roles permission. The slug "owner" is reserved and cannot be used for custom roles.

Body fields

action
string
required
"createOrgRole"
orgId
string
required
ID of the organization.
name
string
required
Role display name. 1–80 characters.
slug
string
URL-safe slug for the role. Lowercase alphanumeric with hyphens; 2–32 characters; must start and end with alphanumeric. If omitted, auto-generated from name. Cannot be "owner".
permissions
object
required
An object mapping permission keys to boolean values. Any key not included defaults to false. See Org permission model for the full list of keys.

Example

curl --request POST \
  --url https://your-api.example.com/v1/workspace/actions \
  --header 'Authorization: Bearer <your-session-token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "action": "createOrgRole",
    "orgId": "org_01j9z8aabbccdd",
    "name": "Compliance Agent",
    "slug": "compliance-agent",
    "permissions": {
      "orgSettings": false,
      "brand": false,
      "locations": true,
      "roles": false,
      "members": false,
      "billing": false
    }
  }'

Update role permissions

action: updateOrgRolePermissions Updates the permission set for an existing custom role. Requires the roles permission. The built-in owner role cannot be modified through this action.

Body fields

action
string
required
"updateOrgRolePermissions"
orgId
string
required
ID of the organization.
roleId
string
required
ID of the role to update. Must belong to the specified organization. Cannot be the owner role.
permissions
object
required
Updated permission map. Any key not included defaults to false.

Delete role

action: deleteOrgRole Permanently removes a custom role from the organization. The built-in owner role cannot be deleted. Roles with active members must have all members reassigned before deletion. Requires the roles permission.

Body fields

action
string
required
"deleteOrgRole"
orgId
string
required
ID of the organization.
roleId
string
required
ID of the role to delete. Must have zero assigned members.

Invite member by email

action: inviteOrgMember Creates a pending invitation for an email address. The invited user appears in the member list with status: "INVITED" and a synthetic userId of "invite:<email>". Requires the members permission.

Body fields

action
string
required
"inviteOrgMember"
orgId
string
required
ID of the organization.
email
string
required
Email address to invite. Must be a valid email; maximum 254 characters.
roleSlug
string
Slug of the role to assign to the invited member. Defaults to "owner" if omitted. The role must already exist in the organization.

Add member by user ID

action: addOrgMemberByUserId Directly adds an existing Clerk user to the organization as an active member. Use this when you already know the user’s Clerk ID rather than their email address. Requires the members permission.

Body fields

action
string
required
"addOrgMemberByUserId"
orgId
string
required
ID of the organization.
newUserId
string
required
Clerk user ID of the user to add. Must start with "user_".
roleSlug
string
Slug of the role to assign. Defaults to "owner" if omitted.

Update member role

action: updateOrgMemberRole Changes the role assigned to an existing member. Requires the members permission.

Body fields

action
string
required
"updateOrgMemberRole"
orgId
string
required
ID of the organization.
memberId
string
required
ID of the membership record to update.
roleSlug
string
required
Slug of the new role to assign. 1–40 characters. The role must exist in the organization.

Remove member

action: removeOrgMember Removes a member from the organization. The organization owner cannot be removed. Requires the members permission.

Body fields

action
string
required
"removeOrgMember"
orgId
string
required
ID of the organization.
memberId
string
required
ID of the membership record to remove.

Update billing account

action: updateBillingAccount Updates the billing account for an organization. Requires the billing permission.
This action updates billing records directly. For Stripe-managed subscriptions, use the Stripe integration to initiate checkout or portal sessions rather than writing Stripe IDs directly.

Body fields

action
string
required
"updateBillingAccount"
orgId
string
required
ID of the organization.
planTier
string
required
Subscription tier. One of "FREE", "STARTER", "PRO", "ENTERPRISE".
status
string
required
Billing status. One of "NONE", "ACTIVE", "PAST_DUE", "CANCELED".
stripeCustomerId
string or null
Stripe customer ID. Maximum 120 characters. Pass null to clear.
stripeSubscriptionId
string or null
Stripe subscription ID. Maximum 120 characters. Pass null to clear.

Delete organization

action: deleteOrganization Permanently deletes the organization and all associated data. Only the organization owner can perform this action. It also requires the orgSettings permission.
This action is irreversible. All organization data — locations, roles, members, billing records, and documents — will be permanently deleted.

Body fields

action
string
required
"deleteOrganization"
orgId
string
required
ID of the organization to delete.

Response fields

ok
boolean
required
true on success.
redirectTo
string
required
Always "/orgs". Clients should redirect the user here after a successful deletion.

Upsert user profile

action: upsertUserProfile Creates or updates your own user profile. All fields are optional; omitted fields are set to null. The publicSlug, if provided, must be unique across all users and follow the same format rules as org slugs (lowercase alphanumeric with hyphens, 2–48 characters).

Body fields

action
string
required
"upsertUserProfile"
displayName
string or null
Preferred display name. Maximum 120 characters.
title
string or null
Job title or role description. Maximum 120 characters.
bio
string or null
Short biography. Maximum 2000 characters.
avatarUrl
string or null
URL to your avatar image. Maximum 2000 characters.
tileAccent
string or null
Accent color or style token for profile tile display. Maximum 32 characters.
publicSlug
string or null
Public profile slug. Lowercase alphanumeric with hyphens; 2–48 characters; must start and end with alphanumeric. Must be globally unique.

Example

curl --request POST \
  --url https://your-api.example.com/v1/workspace/actions \
  --header 'Authorization: Bearer <your-session-token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "action": "upsertUserProfile",
    "displayName": "Jordan Smith",
    "title": "Compliance Officer",
    "bio": "Specializing in chattel document compliance for manufactured housing.",
    "avatarUrl": "https://cdn.example.com/avatars/jordan.jpg",
    "tileAccent": "blue",
    "publicSlug": "jordan-smith"
  }'

Org permission model

Every organization member is assigned a role. Each role carries a permissions object with six boolean keys. Permissions default to false for custom roles; the built-in owner role always has all permissions set to true.
Permission keyWhat it controls
orgSettingsUpdate the organization name and slug; delete the organization
brandCustomize brand name, logo URL, and primary color
locationsAdd, edit, and remove locations
rolesCreate custom roles, update role permissions, delete roles
membersInvite members by email or user ID, update member roles, remove members
billingUpdate billing account tier, status, and Stripe identifiers
Organization owners always have all six permissions regardless of what is stored in the role’s permissions field. The owner role is a built-in role (isBuiltIn: true) with slug "owner" and cannot be deleted or have its permissions modified through the API.
To check your current permissions for a specific organization, call GET /v1/workspace/org-bundle/:orgId. The response includes your assigned role object with its full permissions map, as well as the complete list of roles defined for the organization.

Error cases

StatusError messageCause
400"Invalid body." with issuesRequest body failed schema validation.
400"That slug is already taken."A different organization already uses the requested org slug.
400"Slug must be 2–48 chars, lowercase letters, numbers, hyphens; start/end with alphanumeric."Org slug format is invalid.
400"Not a member of this organization."You are not an active member of the target org.
400"You do not have permission for this action."Your role does not include the required permission key.
400"Cannot remove the organization owner."Attempted to remove the member who owns the org.
400"Reassign members before deleting this role."Role still has members assigned.
400"Cannot delete owner role."Attempted to delete the built-in owner role.
400"Cannot change owner permissions here."Attempted to modify the owner role’s permissions.
400"Only the owner can delete the workspace."Attempted deleteOrganization without being the org owner.
400"Primary color must be #RRGGBB hex."brandPrimaryHex was not a valid 6-digit hex color.
400"That public slug is already taken."Another user’s profile already uses the requested public slug.
401Missing Authorization Bearer token.No Authorization header was sent.
401Invalid or expired token.The Bearer token is malformed or has expired.