Knowledge Roles API
Manage role-based access control (RBAC) for knowledge items. These endpoints allow you to assign and unassign roles to specific knowledge items, controlling which users can access each piece of content based on their assigned roles.
Prerequisites
Before using these endpoints, ensure that:
- RBAC is enabled for your workspace (see Roles API)
- Roles have been created in your workspace
- You have your workspace API key
Available Endpoints
List Roles for Knowledge
GET /v1/workspaces/{workspaceId}/knowledge/{knowledgeId}/role
Get all roles assigned to a specific knowledge item.
Assign Roles to Knowledge
POST /v1/workspaces/{workspaceId}/knowledge/{knowledgeId}/role
Assign multiple roles to a knowledge item.
Unassign Roles from Knowledge
DELETE /v1/workspaces/{workspaceId}/knowledge/{knowledgeId}/role
Remove role assignments from a knowledge item.
List Roles
Get all roles currently assigned to a specific knowledge item.
Endpoint
GET /v1/workspaces/{workspaceId}/knowledge/{knowledgeId}/roleAuthentication
Requires Bearer token authentication. See Authentication for details.
Authorization: Bearer YOUR_ACCESS_TOKENPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string (UUID) | Yes | The ID of your workspace |
knowledgeId | string (UUID) | Yes | The ID of the knowledge item |
Response
Success Response
Status Code: 200 OK
Headers:
X-API-Version: v1Body:
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Sales Team",
"description": "Access for sales team members",
"metadata": {
"department": "sales",
"level": "standard"
}
},
{
"id": "789e0123-f45a-67b8-c901-234567890def",
"name": "Support Team",
"description": "Access for customer support",
"metadata": {
"department": "support",
"level": "premium"
}
}
]Response Fields
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique identifier for the role |
name | string | Role name |
description | string | Role description |
metadata | object | Custom metadata associated with the role |
Example
curl -X GET \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/knowledge/550e8400-e29b-41d4-a716-446655440000/role' \
-H 'x-api-key: sk-sharely-your-api-key'Response:
[
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Sales Team",
"description": "Sales team role",
"metadata": {}
}
]Assign Roles
Assign multiple roles to a knowledge item. This is an asynchronous operation that processes role assignments in the background.
Endpoint
POST /v1/workspaces/{workspaceId}/knowledge/{knowledgeId}/roleAuthentication
Requires Bearer token authentication. See Authentication for details.
Authorization: Bearer YOUR_ACCESS_TOKENPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string (UUID) | Yes | The ID of your workspace |
knowledgeId | string (UUID) | Yes | The ID of the knowledge item |
Headers
| Header | Type | Required | Description |
|---|---|---|---|
organizationId | string (UUID) | Yes | Your organization ID |
x-api-key | string | Yes | Your workspace API key |
Content-Type | string | Yes | Must be application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
roleIds | array of string (UUID) | Yes | Array of role IDs to assign to this knowledge item |
Response
Success Response
Status Code: 200 OK
Headers:
X-API-Version: v1Body:
{
"workspaceId": "your-workspace-id",
"knowledgeId": "550e8400-e29b-41d4-a716-446655440000",
"organizationId": "your-organization-id",
"roleIds": [
"123e4567-e89b-12d3-a456-426614174000",
"789e0123-f45a-67b8-c901-234567890def"
]
}Notes
Asynchronous Processing
Role assignment is an asynchronous operation. The API returns immediately and processes the assignments in the background using a Temporal workflow. A background job is created to track the operation.
Important: Currently, there is no v1 API endpoint to check the status of these async operations when using API key authentication. The workflow processes in the background and you can verify completion by:
- Calling the List Roles endpoint to see if roles have been assigned
- Implementing a polling mechanism to check role assignments
- Using the user-authenticated endpoint
GET /workspaces/{workspaceId}/role/statusif you have user credentials (not recommended for API key workflows)
Recommendation: Treat these operations as eventually consistent. The role assignments typically complete within seconds, but may take longer for large batches.
Future Enhancement: The following v1 API endpoints are planned to support workflow status checking with API key authentication:
GET /v1/workspaces/{workspaceId}/workflows/{workflowId}/status- Check status of any workflow by IDGET /v1/workspaces/{workspaceId}/background-jobs- List all background jobs for the workspaceGET /v1/workspaces/{workspaceId}/background-jobs/{jobId}- Get specific background job status
These endpoints will return workflow status information including:
status: Current workflow state (RUNNING, COMPLETED, FAILED, etc.)progress: Percentage complete for long-running operationsresult: Final result data when completederror: Error details if the workflow failed
RBAC Requirements
- RBAC must be enabled for your workspace (
rbacStatus === ACTIVE) - The workspace must not be deleted
- All role IDs must exist in the workspace
Example
curl -X POST \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/knowledge/550e8400-e29b-41d4-a716-446655440000/role' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'organizationid: your-organization-id' \
-H 'organizationId: your-organization-id' \
-H 'Content-Type: application/json' \
-d '{
"roleIds": [
"123e4567-e89b-12d3-a456-426614174000",
"789e0123-f45a-67b8-c901-234567890def"
]
}'Response:
{
"workspaceId": "your-workspace-id",
"knowledgeId": "550e8400-e29b-41d4-a716-446655440000",
"organizationId": "your-organization-id",
"roleIds": [
"123e4567-e89b-12d3-a456-426614174000",
"789e0123-f45a-67b8-c901-234567890def"
]
}Unassign Roles
Remove role assignments from a knowledge item. This is an asynchronous operation that processes role removal in the background.
Endpoint
DELETE /v1/workspaces/{workspaceId}/knowledge/{knowledgeId}/roleAuthentication
Requires Bearer token authentication. See Authentication for details.
Authorization: Bearer YOUR_ACCESS_TOKENPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string (UUID) | Yes | The ID of your workspace |
knowledgeId | string (UUID) | Yes | The ID of the knowledge item |
Headers
| Header | Type | Required | Description |
|---|---|---|---|
organizationId | string (UUID) | Yes | Your organization ID |
x-api-key | string | Yes | Your workspace API key |
Content-Type | string | Yes | Must be application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
roleIds | array of string (UUID) | Yes | Array of role IDs to remove from this knowledge item |
Response
Success Response
Status Code: 200 OK
Headers:
X-API-Version: v1Body:
{
"workspaceId": "your-workspace-id",
"knowledgeId": "550e8400-e29b-41d4-a716-446655440000",
"organizationId": "your-organization-id",
"roleIds": [
"123e4567-e89b-12d3-a456-426614174000"
]
}Notes
Asynchronous Processing
Role unassignment is an asynchronous operation. The API returns immediately and processes the removals in the background using a Temporal workflow.
Status Checking: See the note in the Assign Roles section about checking async operation status. The same limitations and recommendations apply.
RBAC Requirements
- RBAC must be enabled for your workspace
- The workspace must not be deleted
- Removing a role makes the knowledge item inaccessible to users with only that role
Example
curl -X DELETE \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/knowledge/550e8400-e29b-41d4-a716-446655440000/role' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'organizationid: your-organization-id' \
-H 'organizationId: your-organization-id' \
-H 'Content-Type: application/json' \
-d '{
"roleIds": [
"123e4567-e89b-12d3-a456-426614174000"
]
}'Response:
{
"workspaceId": "your-workspace-id",
"knowledgeId": "550e8400-e29b-41d4-a716-446655440000",
"organizationId": "your-organization-id",
"roleIds": [
"123e4567-e89b-12d3-a456-426614174000"
]
}Error Responses
400 Bad Request
Invalid request parameters:
{
"error": "Bad Request",
"message": "roleIds must be an array of valid UUIDs"
}401 Unauthorized
Invalid or missing API key:
{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}403 Forbidden
RBAC not enabled:
{
"error": "Forbidden",
"message": "RBAC is not enabled for this workspace"
}404 Not Found
Workspace, knowledge item, or role not found:
{
"error": "Not Found",
"message": "Workspace not found"
}{
"error": "Not Found",
"message": "Knowledge item not found"
}{
"error": "Not Found",
"message": "One or more roles not found"
}410 Gone
Workspace deleted:
{
"error": "Gone",
"message": "Workspace is deleted"
}500 Internal Server Error
Server error during processing:
{
"error": "Internal Server Error",
"message": "Failed to process role assignment"
}Common Use Cases
Restrict Knowledge to Specific Teams
Assign knowledge items to specific team roles to control access:
const API_KEY = 'sk-sharely-your-api-key';
const WORKSPACE_ID = 'your-workspace-id';
const ORGANIZATION_ID = 'your-organization-id';
const BASE_URL = 'https://api.sharely.ai';
async function restrictKnowledgeToTeams(knowledgeId, roleIds) {
const response = await fetch(
`${BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge/${knowledgeId}/role`,
{
method: 'POST',
headers: {
'x-api-key': API_KEY,
'organizationId': ORGANIZATION_ID,
'Content-Type': 'application/json'
},
body: JSON.stringify({ roleIds })
}
);
if (!response.ok) {
throw new Error(`Failed to assign roles: ${response.statusText}`);
}
return await response.json();
}
// Restrict sales documentation to sales and management teams
const salesDocId = '550e8400-e29b-41d4-a716-446655440000';
const salesRoleId = '123e4567-e89b-12d3-a456-426614174000';
const managementRoleId = '789e0123-f45a-67b8-c901-234567890def';
await restrictKnowledgeToTeams(salesDocId, [salesRoleId, managementRoleId]);
console.log('Knowledge restricted to sales and management teams');Audit Knowledge Access
Check which roles have access to a knowledge item:
async function auditKnowledgeAccess(knowledgeId) {
const response = await fetch(
`${BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge/${knowledgeId}/role`,
{
method: 'GET',
headers: {
'x-api-key': API_KEY
}
}
);
if (!response.ok) {
throw new Error(`Failed to fetch roles: ${response.statusText}`);
}
const roles = await response.json();
console.log(`Knowledge item ${knowledgeId} is accessible to:`);
roles.forEach(role => {
console.log(`- ${role.name} (${role.id})`);
});
return roles;
}
await auditKnowledgeAccess('550e8400-e29b-41d4-a716-446655440000');Bulk Role Assignment
Assign the same roles to multiple knowledge items:
async function bulkAssignRoles(knowledgeIds, roleIds) {
const results = [];
for (const knowledgeId of knowledgeIds) {
try {
const result = await restrictKnowledgeToTeams(knowledgeId, roleIds);
results.push({
knowledgeId,
status: 'success',
data: result
});
} catch (error) {
results.push({
knowledgeId,
status: 'error',
error: error.message
});
}
// Rate limiting
await new Promise(resolve => setTimeout(resolve, 100));
}
return results;
}
// Assign sales and support roles to multiple knowledge items
const knowledgeIds = [
'550e8400-e29b-41d4-a716-446655440000',
'789e0123-f45a-67b8-c901-234567890def',
'456e7890-a12b-34c5-d678-901234567890'
];
const roleIds = [
'123e4567-e89b-12d3-a456-426614174000', // Sales
'789e0123-f45a-67b8-c901-234567890def' // Support
];
const results = await bulkAssignRoles(knowledgeIds, roleIds);
console.log(`Successfully assigned: ${results.filter(r => r.status === 'success').length}`);
console.log(`Failed: ${results.filter(r => r.status === 'error').length}`);Update Knowledge Permissions
Replace existing role assignments with new ones:
async function updateKnowledgePermissions(knowledgeId, newRoleIds) {
// Step 1: Get current roles
const currentRoles = await fetch(
`${BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge/${knowledgeId}/role`,
{
method: 'GET',
headers: { 'x-api-key': API_KEY }
}
).then(r => r.json());
// Step 2: Remove all current roles
if (currentRoles.length > 0) {
const currentRoleIds = currentRoles.map(r => r.id);
await fetch(
`${BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge/${knowledgeId}/role`,
{
method: 'DELETE',
headers: {
'x-api-key': API_KEY,
'organizationId': ORGANIZATION_ID,
'Content-Type': 'application/json'
},
body: JSON.stringify({ roleIds: currentRoleIds })
}
);
}
// Step 3: Assign new roles
await fetch(
`${BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge/${knowledgeId}/role`,
{
method: 'POST',
headers: {
'x-api-key': API_KEY,
'organizationId': ORGANIZATION_ID,
'Content-Type': 'application/json'
},
body: JSON.stringify({ roleIds: newRoleIds })
}
);
console.log(`Updated permissions for knowledge ${knowledgeId}`);
}
// Change from sales-only to sales and management
await updateKnowledgePermissions(
'550e8400-e29b-41d4-a716-446655440000',
['123e4567-e89b-12d3-a456-426614174000', '789e0123-f45a-67b8-c901-234567890def']
);Python Example
import requests
from typing import List
API_KEY = 'sk-sharely-your-api-key'
WORKSPACE_ID = 'your-workspace-id'
ORGANIZATION_ID = 'your-organization-id'
BASE_URL = 'https://api.sharely.ai'
def assign_roles_to_knowledge(knowledge_id: str, role_ids: List[str]):
"""Assign multiple roles to a knowledge item"""
response = requests.post(
f'{BASE_URL}/v1/workspaces/{WORKSPACE_ID}/knowledge/{knowledge_id}/role',
headers={
'x-api-key': API_KEY,
'organizationId': ORGANIZATION_ID,
'Content-Type': 'application/json'
},
json={'roleIds': role_ids}
)
response.raise_for_status()
return response.json()
def get_knowledge_roles(knowledge_id: str):
"""Get all roles assigned to a knowledge item"""
response = requests.get(
f'{BASE_URL}/v1/workspaces/{WORKSPACE_ID}/knowledge/{knowledge_id}/role',
headers={'x-api-key': API_KEY}
)
response.raise_for_status()
return response.json()
def remove_roles_from_knowledge(knowledge_id: str, role_ids: List[str]):
"""Remove role assignments from a knowledge item"""
response = requests.delete(
f'{BASE_URL}/v1/workspaces/{WORKSPACE_ID}/knowledge/{knowledge_id}/role',
headers={
'x-api-key': API_KEY,
'organizationId': ORGANIZATION_ID,
'Content-Type': 'application/json'
},
json={'roleIds': role_ids}
)
response.raise_for_status()
return response.json()
# Usage
knowledge_id = '550e8400-e29b-41d4-a716-446655440000'
sales_role_id = '123e4567-e89b-12d3-a456-426614174000'
support_role_id = '789e0123-f45a-67b8-c901-234567890def'
# Assign roles
result = assign_roles_to_knowledge(knowledge_id, [sales_role_id, support_role_id])
print(f"Assigned roles: {result}")
# List current roles
roles = get_knowledge_roles(knowledge_id)
print(f"Current roles: {[role['name'] for role in roles]}")
# Remove a role
remove_roles_from_knowledge(knowledge_id, [support_role_id])
print("Removed support role")Best Practices
Role Validation
Always verify that roles exist before assigning them:
async function validateAndAssignRoles(knowledgeId, roleIds) {
// Validate each role exists
for (const roleId of roleIds) {
try {
const response = await fetch(
`${BASE_URL}/v1/workspaces/${WORKSPACE_ID}/role/${roleId}`,
{
headers: { 'x-api-key': API_KEY }
}
);
if (!response.ok) {
throw new Error(`Role ${roleId} not found`);
}
} catch (error) {
console.error(`Validation failed: ${error.message}`);
return null;
}
}
// All roles valid, proceed with assignment
return await restrictKnowledgeToTeams(knowledgeId, roleIds);
}Error Handling
Handle asynchronous processing errors gracefully:
async function safeAssignRoles(knowledgeId, roleIds) {
try {
const result = await fetch(
`${BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge/${knowledgeId}/role`,
{
method: 'POST',
headers: {
'x-api-key': API_KEY,
'organizationId': ORGANIZATION_ID,
'Content-Type': 'application/json'
},
body: JSON.stringify({ roleIds })
}
);
if (!result.ok) {
const error = await result.json();
console.error('Assignment failed:', error);
// Handle specific errors
if (error.message?.includes('RBAC is not enabled')) {
console.error('Please enable RBAC for your workspace first');
}
return null;
}
return await result.json();
} catch (error) {
console.error('Network error:', error);
return null;
}
}Rate Limiting
When processing multiple knowledge items, implement rate limiting:
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function bulkAssignWithRateLimit(assignments, requestsPerSecond = 5) {
const delayMs = 1000 / requestsPerSecond;
const results = [];
for (const { knowledgeId, roleIds } of assignments) {
const result = await safeAssignRoles(knowledgeId, roleIds);
results.push({ knowledgeId, result });
// Wait before next request
await sleep(delayMs);
}
return results;
}Verifying Async Completion
Since there's no direct status endpoint for API key authenticated operations, implement polling to verify completion:
async function waitForRoleAssignment(knowledgeId, expectedRoleIds, maxWaitMs = 30000) {
const startTime = Date.now();
const pollInterval = 1000; // Check every second
while (Date.now() - startTime < maxWaitMs) {
// Get current roles
const roles = await fetch(
`${BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge/${knowledgeId}/role`,
{
method: 'GET',
headers: { 'x-api-key': API_KEY }
}
).then(r => r.json());
// Check if all expected roles are present
const currentRoleIds = roles.map(r => r.id);
const allPresent = expectedRoleIds.every(id => currentRoleIds.includes(id));
if (allPresent) {
console.log('Role assignment completed');
return true;
}
// Wait before next check
await new Promise(resolve => setTimeout(resolve, pollInterval));
}
throw new Error('Timeout waiting for role assignment');
}
// Usage
await restrictKnowledgeToTeams(knowledgeId, [roleId1, roleId2]);
await waitForRoleAssignment(knowledgeId, [roleId1, roleId2]);
console.log('Roles successfully assigned and verified');Idempotency
Assignment operations are idempotent - assigning the same role multiple times has the same effect as assigning it once:
// Safe to call multiple times
await restrictKnowledgeToTeams(knowledgeId, [roleId]);
await restrictKnowledgeToTeams(knowledgeId, [roleId]); // No error, no duplicateIntegration with Other APIs
Create Knowledge and Assign Roles
async function createRestrictedKnowledge(content, roleIds) {
// Step 1: Create knowledge
const createResponse = await fetch(
`${BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${ACCESS_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: 'STRING',
content: content,
title: 'Restricted Document'
})
}
);
const { id: knowledgeId } = await createResponse.json();
// Step 2: Assign roles
await restrictKnowledgeToTeams(knowledgeId, roleIds);
return knowledgeId;
}Sync Roles Across Knowledge Items
async function syncRolesAcrossKnowledge(sourceKnowledgeId, targetKnowledgeIds) {
// Get roles from source
const sourceRoles = await get_knowledge_roles(sourceKnowledgeId);
const roleIds = sourceRoles.map(r => r.id);
// Apply to all targets
const results = await bulkAssignRoles(targetKnowledgeIds, roleIds);
return results;
}Related APIs
- Roles API - Create and manage roles for your workspace
- Knowledge API - Create and manage knowledge items
- Spaces API - Provision user spaces with role-based access