Upsert Role
Create or update a role based on customer role ID. This is an idempotent operation that creates a new role if it doesn't exist, or updates the existing role if it does.
Endpoint
POST /v1/workspaces/{workspaceId}/role/upsertAuthentication
Requires Bearer token authentication. See Authentication for details on obtaining an access token.
Authorization: Bearer YOUR_ACCESS_TOKENPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string (UUID) | Yes | The ID of your workspace |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
customerRoleId | string | Yes | Your custom role identifier (used to determine if role exists) |
name | string | No | Display name for the role |
description | string | No | Description of the role's purpose |
Response
Success Response
Status Code: 200 OK (update) or 201 Created (create)
Headers:
X-API-Version: v1Body:
{
"workflowId": "550e8400-e29b-41d4-a716-446655440000",
"role": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Sales Manager",
"description": "Access to sales-related content",
"customerRoleId": "sales-manager",
"createdAt": "2025-11-11T10:00:00Z",
"updatedAt": "2025-11-11T15:30:00Z"
},
"created": false
}| Field | Type | Description |
|---|---|---|
workflowId | string (UUID) | Workflow ID for tracking the async operation |
role | object | The created or updated role object |
created | boolean | true if role was created, false if updated |
Examples
Create New Role via Upsert
When no role with the customer role ID exists:
curl -X POST \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/role/upsert' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'organizationid: your-organization-id' \
-H 'Content-Type: application/json' \
-d '{
"customerRoleId": "sales-manager",
"name": "Sales Manager",
"description": "Access to sales content"
}'Response:
{
"workflowId": "789e0123-f45a-67b8-c901-234567890def",
"role": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Sales Manager",
"description": "Access to sales content",
"customerRoleId": "sales-manager",
"createdAt": "2025-11-11T14:30:00Z",
"updatedAt": "2025-11-11T14:30:00Z"
},
"created": true
}Update Existing Role via Upsert
When a role with the customer role ID already exists:
curl -X POST \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/role/upsert' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'organizationid: your-organization-id' \
-H 'Content-Type: application/json' \
-d '{
"customerRoleId": "sales-manager",
"name": "Senior Sales Manager",
"description": "Enhanced sales content access"
}'Response:
{
"workflowId": "456e7890-a12b-34c5-d678-901234567890",
"role": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Senior Sales Manager",
"description": "Enhanced sales content access",
"customerRoleId": "sales-manager",
"createdAt": "2025-11-11T14:30:00Z",
"updatedAt": "2025-11-11T16:45:00Z"
},
"created": false
}Idempotent Role Provisioning
Run the same upsert multiple times safely:
# First call - creates role
curl -X POST \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/role/upsert' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'organizationid: your-organization-id' \
-H 'Content-Type: application/json' \
-d '{
"customerRoleId": "admin",
"name": "Administrator",
"description": "Full access"
}'
# Second call - updates existing role (no error)
curl -X POST \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/role/upsert' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'organizationid: your-organization-id' \
-H 'Content-Type: application/json' \
-d '{
"customerRoleId": "admin",
"name": "Administrator",
"description": "Full access"
}'Error Responses
400 Bad Request
Missing required field:
{
"error": "Bad Request",
"message": "Missing required field: customerRoleId"
}401 Unauthorized
{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}500 Internal Server Error
{
"error": "Internal Server Error",
"message": "Failed to upsert role"
}Notes
Idempotency
This endpoint is idempotent - you can call it multiple times with the same customerRoleId safely:
- First call: Creates the role
- Subsequent calls: Update the role with new values
- No 409 Conflict errors
Customer Role ID Required
Unlike the create endpoint, customerRoleId is required for upsert. This is because it's used to determine whether to create or update.
Determination Logic
The endpoint determines whether to create or update based on:
- Search for existing role with matching
customerRoleId - If found: Update that role
- If not found: Create new role
Asynchronous Processing
Like create and update operations, upsert is asynchronous. Track progress using the returned workflowId.
Best Practices
Use for Synchronization
Perfect for keeping roles synchronized with external systems:
async function syncRole(workspaceId, externalRole) {
await fetch(
`https://api.sharely.ai/v1/workspaces/${workspaceId}/role/upsert`,
{
method: 'POST',
headers: {
'x-api-key': 'sk-sharely-your-api-key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
customerRoleId: externalRole.id,
name: externalRole.name,
description: externalRole.description
})
}
);
}Infrastructure as Code
Use in deployment scripts for consistent role provisioning:
#!/bin/bash
# Ensure roles exist with specific configuration
roles=(
"admin:Administrator:Full system access"
"editor:Content Editor:Can edit content"
"viewer:Viewer:Read-only access"
)
for role in "${roles[@]}"; do
IFS=: read -r id name desc <<< "$role"
curl -X POST \
"https://api.sharely.ai/v1/workspaces/${WORKSPACE_ID}/role/upsert" \
-H "x-api-key: ${API_KEY}" \
-H 'Content-Type: application/json' \
-d "{
\"customerRoleId\": \"$id\",
\"name\": \"$name\",
\"description\": \"$desc\"
}"
doneAutomated Provisioning
Ideal for automated user provisioning workflows where you need to ensure roles exist.
Related Endpoints
- Create Role - Create only (fails if exists)
- Update Role - Update only (fails if doesn't exist)
- Find Roles - Check existence before upserting
- Get by Customer Role ID - Verify result
Use Cases
CI/CD Pipeline
Ensure roles exist in each environment:
# .github/workflows/deploy.yml
- name: Provision Roles
run: |
curl -X POST \
"https://api.sharely.ai/v1/workspaces/${{ secrets.WORKSPACE_ID }}/role/upsert" \
-H "x-api-key: ${{ secrets.API_KEY }}" \
-H 'Content-Type: application/json' \
-d '{"customerRoleId": "admin", "name": "Admin", "description": "Full access"}'Configuration Management
Maintain role configurations in code:
const roleConfigs = [
{ customerRoleId: 'admin', name: 'Administrator', description: 'Full access' },
{ customerRoleId: 'editor', name: 'Editor', description: 'Edit content' },
{ customerRoleId: 'viewer', name: 'Viewer', description: 'View only' }
];
async function ensureRoles(workspaceId) {
for (const config of roleConfigs) {
await fetch(
`https://api.sharely.ai/v1/workspaces/${workspaceId}/role/upsert`,
{
method: 'POST',
headers: {
'x-api-key': 'sk-sharely-your-api-key',
'Content-Type': 'application/json'
},
body: JSON.stringify(config)
}
);
}
}