Search Knowledge
Search and retrieve knowledge items from your workspace using semantic vector search or title matching. This endpoint provides powerful natural language search capabilities across all your knowledge content.
Endpoints
Semantic Search
POST /workspaces/{workspaceId}/knowledge/searchSearch using natural language queries with vector similarity matching.
Title Search
POST /workspaces/{workspaceId}/knowledge/search-titleSearch by exact or partial title matching.
Authentication
This endpoint requires a Bearer token obtained through the two-step authentication flow:
- First, generate an access token using your API key
- Use that access token in the Authorization header
See Authentication for the complete authentication flow.
Required Headers:
Authorization: Bearer {access_token}- The JWT access token (NOT your raw API key)x-api-key: {your-api-key}- Your workspace API key
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string (UUID) | Yes | The ID of your workspace |
Request Body
Semantic Search Parameters
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Natural language search query |
limit | integer | No | Maximum number of results. Default: 10, Max: 50 |
audienceId | string (UUID) | No | Filter results by audience ID |
roleIds | array[string] | No | Filter results by role IDs (RBAC) |
Title Search Parameters
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Title to search for (partial match supported) |
limit | integer | No | Maximum number of results. Default: 10, Max: 50 |
audienceId | string (UUID) | No | Filter results by audience ID |
roleIds | array[string] | No | Filter results by role IDs (RBAC) |
Response
Success Response
Status Code: 200 OK
Headers:
X-API-Version: v1Body:
{
"results": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Product Documentation",
"type": "FILE",
"url": "https://example.com/doc.pdf",
"content": "Excerpt of the content...",
"metadata": {
"category": "Documentation",
"author": "John Doe"
},
"score": 0.92,
"createdAt": "2025-01-15T10:30:00Z",
"updatedAt": "2025-01-15T10:30:00Z"
}
],
"total": 1
}Response Fields
| Field | Type | Description |
|---|---|---|
results | array | Array of matching knowledge items |
results[].id | string (UUID) | Unique identifier for the knowledge item |
results[].title | string | Title of the knowledge item |
results[].type | string | Knowledge type: FILE, URL, LINK, or STRING |
results[].url | string | URL or file path |
results[].content | string | Content excerpt (first 500 characters) |
results[].metadata | object | Custom metadata associated with the knowledge |
results[].score | number | Relevance score (0-1) for semantic search |
results[].createdAt | string (ISO 8601) | Creation timestamp |
results[].updatedAt | string (ISO 8601) | Last update timestamp |
total | integer | Total number of matching results |
Examples
Semantic Search
Search using natural language:
# Step 1: Generate access token (do this once, reuse for multiple requests)
ACCESS_TOKEN=$(curl -s -X POST \
'https://api.sharely.ai/workspaces/your-workspace-id/generate-access-key-token' \
-H 'Content-Type: application/json' \
-H 'x-api-key: sk-sharely-your-api-key' \
-d '{}' | jq -r '.token')
# Step 2: Search using the access token
curl -X POST \
'https://api.sharely.ai/workspaces/your-workspace-id/knowledge/search' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'x-api-key: sk-sharely-your-api-key' \
-H 'Content-Type: application/json' \
-d '{
"query": "how to install the product",
"limit": 10
}'Response:
{
"results": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Installation Guide",
"type": "FILE",
"url": "https://storage.example.com/install-guide.pdf",
"content": "This guide explains how to install the product step by step...",
"metadata": {
"category": "Documentation",
"version": "2.0"
},
"score": 0.95,
"createdAt": "2025-01-10T14:20:00Z",
"updatedAt": "2025-01-10T14:20:00Z"
},
{
"id": "987fcdeb-51a2-43f7-b8c9-123456789abc",
"title": "Quick Start Guide",
"type": "URL",
"url": "https://docs.example.com/quickstart",
"content": "Get started in minutes with our product...",
"metadata": {
"category": "Getting Started"
},
"score": 0.87,
"createdAt": "2025-01-12T09:15:00Z",
"updatedAt": "2025-01-12T09:15:00Z"
}
],
"total": 2
}Title Search
Search by title:
# Using the access token from Step 1 above
curl -X POST \
'https://api.sharely.ai/workspaces/your-workspace-id/knowledge/search-title' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'x-api-key: sk-sharely-your-api-key' \
-H 'Content-Type: application/json' \
-d '{
"title": "Installation",
"limit": 5
}'Response:
{
"results": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Installation Guide",
"type": "FILE",
"url": "https://storage.example.com/install-guide.pdf",
"content": "Complete installation instructions...",
"metadata": {
"category": "Documentation"
},
"createdAt": "2025-01-10T14:20:00Z",
"updatedAt": "2025-01-10T14:20:00Z"
}
],
"total": 1
}Search with Audience Filter
Filter results by audience:
curl -X POST \
'https://api.sharely.ai/workspaces/your-workspace-id/knowledge/search' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'x-api-key: sk-sharely-your-api-key' \
-H 'Content-Type: application/json' \
-d '{
"query": "API documentation",
"audienceId": "456e7890-e12b-34d5-a678-426614174999",
"limit": 10
}'Search with Role-Based Access Control
Filter by role IDs for RBAC:
curl -X POST \
'https://api.sharely.ai/workspaces/your-workspace-id/knowledge/search' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'x-api-key: sk-sharely-your-api-key' \
-H 'Content-Type: application/json' \
-d '{
"query": "sensitive documentation",
"roleIds": ["role-123", "role-456"],
"limit": 10
}'JavaScript Example
const API_KEY = 'sk-sharely-your-api-key';
const WORKSPACE_ID = 'your-workspace-id';
const ORGANIZATION_ID = 'your-organization-id';
const API_BASE_URL = 'https://api.sharely.ai';
// Step 1: Generate access token
async function getAccessToken() {
const response = await fetch(
`${API_BASE_URL}/workspaces/${WORKSPACE_ID}/generate-access-key-token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': API_KEY
},
body: JSON.stringify({})
}
);
if (!response.ok) {
throw new Error(`Failed to get access token: ${response.statusText}`);
}
const data = await response.json();
return data.token;
}
// Step 2: Search knowledge
async function searchKnowledge(accessToken, query, options = {}) {
const response = await fetch(
`${API_BASE_URL}/workspaces/${WORKSPACE_ID}/knowledge/search`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'organizationid': ORGANIZATION_ID,
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: query,
limit: options.limit || 10,
audienceId: options.audienceId,
roleIds: options.roleIds
})
}
);
if (!response.ok) {
throw new Error(`Search failed: ${response.statusText}`);
}
return await response.json();
}
// Usage
const accessToken = await getAccessToken();
// Semantic search
const results = await searchKnowledge(accessToken, 'how to get started', { limit: 10 });
console.log(`Found ${results.total} results`);
results.results.forEach(item => {
console.log(`${item.title} (score: ${item.score})`);
});
// With audience filter
const audienceResults = await searchKnowledge(
accessToken,
'features',
{ audienceId: '456e7890-e12b-34d5-a678-426614174999' }
);Python Example
import requests
API_KEY = 'sk-sharely-your-api-key'
WORKSPACE_ID = 'your-workspace-id'
ORGANIZATION_ID = 'your-organization-id'
API_BASE_URL = 'https://api.sharely.ai'
# Step 1: Generate access token
def get_access_token():
response = requests.post(
f'{API_BASE_URL}/workspaces/{WORKSPACE_ID}/generate-access-key-token',
headers={
'Content-Type': 'application/json',
'x-api-key': API_KEY
},
json={}
)
response.raise_for_status()
return response.json()['token']
# Step 2: Search knowledge
def search_knowledge(access_token, query, limit=10, audience_id=None, role_ids=None):
payload = {
'query': query,
'limit': limit
}
if audience_id:
payload['audienceId'] = audience_id
if role_ids:
payload['roleIds'] = role_ids
response = requests.post(
f'{API_BASE_URL}/workspaces/{WORKSPACE_ID}/knowledge/search',
headers={
'Authorization': f'Bearer {access_token}',
'organizationid': ORGANIZATION_ID,
'Content-Type': 'application/json'
},
json=payload
)
response.raise_for_status()
return response.json()
# Usage
access_token = get_access_token()
# Semantic search
results = search_knowledge(access_token, 'how to install', limit=5)
for item in results['results']:
print(f"{item['title']}: {item['content'][:100]}... (score: {item['score']})")
# With RBAC
results = search_knowledge(
access_token,
'sensitive docs',
role_ids=['role-123', 'role-456']
)Error Responses
400 Bad Request
Missing required parameters:
{
"error": "Bad Request",
"message": "Missing required field: query"
}Invalid parameter type:
{
"error": "Bad Request",
"message": "Invalid limit value. Must be between 1 and 50."
}401 Unauthorized
Invalid or missing API key:
{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}403 Forbidden
Insufficient permissions:
{
"error": "Forbidden",
"message": "Insufficient permissions for this workspace"
}404 Not Found
Invalid workspace or audience ID:
{
"error": "Not Found",
"message": "Workspace or audience not found"
}500 Internal Server Error
Search service error:
{
"error": "Internal Server Error",
"message": "Search service temporarily unavailable"
}Search Types Comparison
Semantic Search (/knowledge/search)
Best for:
- Natural language questions
- Conceptual searches
- Finding related content
- Discovering relevant information
- Understanding context and meaning
How it works:
- Converts query to vector embedding
- Uses vector similarity matching
- Returns results ranked by semantic relevance
- Scores indicate similarity (0-1)
Example queries:
- "How do I reset my password?"
- "Best practices for API integration"
- "Troubleshooting connection issues"
Title Search (/knowledge/search-title)
Best for:
- Finding specific documents by name
- Exact title lookups
- Browsing by name
- Autocomplete functionality
How it works:
- Performs partial string matching on titles
- Case-insensitive matching
- Returns results ordered by creation date
- No relevance scoring
Example queries:
- "Installation Guide"
- "API Reference"
- "User Manual"
Use Cases
Natural Language Q&A
// User asks a question
const question = "What are the system requirements?";
const results = await searchKnowledge(question);
// Display relevant knowledge
results.results.forEach(item => {
console.log(`${item.title}: ${item.content.substring(0, 200)}...`);
});Document Finder
// Find specific documents by title (uses the accessToken from getAccessToken())
async function findDocument(accessToken, titleQuery) {
const response = await fetch(
`${API_BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge/search-title`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'organizationid': ORGANIZATION_ID
},
body: JSON.stringify({ title: titleQuery })
}
);
return await response.json();
}
const accessToken = await getAccessToken();
const docs = await findDocument(accessToken, 'API Reference');Content Discovery
// Discover related content
const related = await searchKnowledge(
'machine learning best practices',
{ limit: 5 }
);Role-Based Content Access
// Search within user's accessible content
const userResults = await searchKnowledge(
'product features',
{ roleIds: currentUser.roleIds }
);Best Practices
Write Effective Queries
// Be specific
const specific = await searchKnowledge('OAuth 2.0 authentication setup');
// Rather than too broad
const broad = await searchKnowledge('authentication');Set Appropriate Limits
// For autocomplete: small limit
const suggestions = await searchKnowledge(userInput, { limit: 5 });
// For comprehensive results: larger limit
const comprehensive = await searchKnowledge(query, { limit: 50 });Handle Empty Results
const results = await searchKnowledge(query);
if (results.total === 0) {
console.log('No results found. Try a different query.');
} else {
displayResults(results.results);
}Use Score Threshold
// Filter by relevance score
const highQualityResults = results.results.filter(item => item.score >= 0.8);Cache Frequent Searches
const searchCache = new Map();
async function cachedSearch(query) {
const cacheKey = `search:${query}`;
if (searchCache.has(cacheKey)) {
return searchCache.get(cacheKey);
}
const results = await searchKnowledge(query);
searchCache.set(cacheKey, results);
// Expire cache after 5 minutes
setTimeout(() => searchCache.delete(cacheKey), 5 * 60 * 1000);
return results;
}Search Algorithm
Semantic Search Process
- Query Processing: Query is converted to a vector embedding using the same model as knowledge content
- Vector Search: Performs cosine similarity search against all knowledge embeddings
- Relevance Ranking: Results are ranked by similarity score (0-1 scale)
- Filtering: Applies audience and role filters if specified
- Limiting: Returns top N results based on limit parameter
Title Search Process
- Pattern Matching: Performs case-insensitive partial match on title field
- Database Query: Uses SQL LIKE or similar for matching
- Filtering: Applies audience and role filters if specified
- Ordering: Results ordered by creation date (newest first)
- Limiting: Returns top N results based on limit parameter
Notes
Search Indexing
- New knowledge items are searchable within seconds of creation
- Semantic search uses vector embeddings for similarity matching
- Search results reflect current RBAC permissions
- Deleted items are removed from search indexes immediately
Result Ordering
- Semantic search: Results ordered by relevance score (highest first)
- Title search: Results ordered by creation date (newest first)
Content Excerpts
Response includes content excerpts (first 500 characters) for preview. Use the Get Knowledge endpoint to retrieve full content.
Audience and Role Filtering
- When
audienceIdis provided, only knowledge assigned to that audience is returned - When
roleIdsis provided, only knowledge accessible to those roles is returned - Both filters can be combined for fine-grained access control
Performance Considerations
- Semantic search is more computationally intensive than title search
- Keep query strings concise for best performance
- Use pagination (limit) to manage large result sets
- Consider caching for frequently searched queries
Search Knowledge by Metadata
Search and filter knowledge items based on specific metadata fields. This endpoint is useful for programmatic filtering by status, type, language, or exact title match.
Endpoint
POST /v1/workspaces/{workspaceId}/knowledge/searchAuthentication
This endpoint requires a Bearer token obtained through the two-step authentication flow:
- First, generate an access token using your API key
- Use that access token in the Authorization header
See Authentication for the complete authentication flow.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string (UUID) | Yes | The ID of your workspace |
Headers
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | Bearer token: Bearer {access_token} |
organizationid | string | Yes | Your organization ID |
Content-Type | string | Yes | Must be application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
metadata | object | Yes | Filter criteria object. Must contain at least one property. |
metadata.status | string | No | Filter by knowledge status: COMPLETED, BACKGROUND_START, BACKGROUND_ERROR |
metadata.type | string | No | Filter by knowledge type: FILE, URL, LINK, STRING |
metadata.language | string | No | Filter by language code (e.g., en, es, fr) |
metadata.title | string | No | Filter by exact title match |
page | integer | No | Page number for pagination. Default: 1 |
limit | integer | No | Number of results per page. Default: 20 |
Important Notes:
- The
metadataobject must contain at least one property - Filters are applied with AND logic (all conditions must match)
- This endpoint uses exact matching, not fuzzy/semantic search
Response
Success Response
Status Code: 200 OK
Body:
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "FILE",
"content": "https://storage.example.com/docs/guide.pdf",
"metadata": {
"title": "Installation Guide",
"language": "en",
"description": "Complete installation instructions"
},
"uploadFileMetadata": {
"filename": "guide.pdf",
"mimetype": "application/pdf"
},
"coreKnowledgeItems": [
{
"id": "item-uuid-123",
"type": "TEXT",
"content": "Chapter 1: Getting Started..."
}
]
}
]Response Fields
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique identifier for the knowledge item |
type | string | Knowledge type: FILE, URL, LINK, or STRING |
content | string | URL or content of the knowledge item |
metadata | object | Custom metadata associated with the knowledge |
uploadFileMetadata | object | File metadata (only for FILE type) |
uploadFileMetadata.filename | string | Original filename |
uploadFileMetadata.mimetype | string | MIME type of the file |
coreKnowledgeItems | array | Processed content items (chunks) |
Examples
Filter by Status
Find all knowledge items that are still processing:
# First, generate access token (see Authentication section)
ACCESS_TOKEN=$(curl -s -X POST \
'https://api.sharely.ai/workspaces/{workspaceId}/generate-access-key-token' \
-H 'Content-Type: application/json' \
-H 'x-api-key: sk-sharely-your-api-key' \
-d '{}' | jq -r '.token')
# Then search with metadata filter
curl -X POST \
'https://api.sharely.ai/v1/workspaces/{workspaceId}/knowledge/search' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'organizationid: your-organization-id' \
-H 'Content-Type: application/json' \
-d '{
"metadata": {
"status": "BACKGROUND_START"
},
"page": 1,
"limit": 20
}'Filter by Type
Find all file uploads:
curl -X POST \
'https://api.sharely.ai/v1/workspaces/{workspaceId}/knowledge/search' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'organizationid: your-organization-id' \
-H 'Content-Type: application/json' \
-d '{
"metadata": {
"type": "FILE"
}
}'Filter by Language
Find all Spanish content:
curl -X POST \
'https://api.sharely.ai/v1/workspaces/{workspaceId}/knowledge/search' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'organizationid: your-organization-id' \
-H 'Content-Type: application/json' \
-d '{
"metadata": {
"language": "es"
}
}'Combined Filters
Find completed FILE type knowledge in English:
curl -X POST \
'https://api.sharely.ai/v1/workspaces/{workspaceId}/knowledge/search' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'organizationid: your-organization-id' \
-H 'Content-Type: application/json' \
-d '{
"metadata": {
"status": "COMPLETED",
"type": "FILE",
"language": "en"
},
"page": 1,
"limit": 50
}'JavaScript Example
const API_KEY = 'sk-sharely-your-api-key';
const WORKSPACE_ID = 'your-workspace-id';
const ORGANIZATION_ID = 'your-organization-id';
const API_BASE_URL = 'https://api.sharely.ai';
// Step 1: Generate access token
async function getAccessToken() {
const response = await fetch(
`${API_BASE_URL}/workspaces/${WORKSPACE_ID}/generate-access-key-token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': API_KEY
},
body: JSON.stringify({})
}
);
const data = await response.json();
return data.token;
}
// Step 2: Search by metadata
async function searchKnowledgeByMetadata(accessToken, filters, options = {}) {
const response = await fetch(
`${API_BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge/search`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'organizationid': ORGANIZATION_ID,
'Content-Type': 'application/json'
},
body: JSON.stringify({
metadata: filters,
page: options.page || 1,
limit: options.limit || 20
})
}
);
if (!response.ok) {
throw new Error(`Search failed: ${response.statusText}`);
}
return await response.json();
}
// Usage
const accessToken = await getAccessToken();
// Find all processing items
const processing = await searchKnowledgeByMetadata(accessToken, { status: 'BACKGROUND_START' });
// Find all English PDFs
const englishFiles = await searchKnowledgeByMetadata(
accessToken,
{ type: 'FILE', language: 'en' },
{ page: 1, limit: 50 }
);Error Responses
400 Bad Request
Empty metadata object:
{
"error": "Validation Error",
"message": "Metadata must contain at least one property"
}Invalid status value:
{
"error": "Validation Error",
"message": "Invalid status value"
}Knowledge Stats
Get aggregated statistics about knowledge items in your workspace, including counts by status and role assignment.
Endpoint
GET /v1/workspaces/{workspaceId}/knowledge/statsAuthentication
This endpoint requires a Bearer token obtained through the two-step authentication flow.
See Authentication for the complete authentication flow.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string (UUID) | Yes | The ID of your workspace |
Headers
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | Bearer token: Bearer {access_token} |
organizationid | string | Yes | Your organization ID |
Response
Success Response
Status Code: 200 OK
Body:
{
"total": 150,
"byStatus": {
"COMPLETED": 142,
"BACKGROUND_START": 5,
"BACKGROUND_ERROR": 3
},
"withRoles": 85,
"withoutRoles": 65,
"withPermissions": 30,
"withoutPermissions": 120
}Response Fields
| Field | Type | Description |
|---|---|---|
total | integer | Total number of knowledge items in the workspace |
byStatus | object | Breakdown of knowledge items by processing status |
byStatus.COMPLETED | integer | Number of fully processed items |
byStatus.BACKGROUND_START | integer | Number of items currently processing |
byStatus.BACKGROUND_ERROR | integer | Number of items that failed processing |
withRoles | integer | Number of items assigned to at least one role |
withoutRoles | integer | Number of items not assigned to any role |
withPermissions | integer | Number of items with custom permissions set |
withoutPermissions | integer | Number of items without custom permissions |
Example
# First, generate access token
ACCESS_TOKEN=$(curl -s -X POST \
'https://api.sharely.ai/workspaces/{workspaceId}/generate-access-key-token' \
-H 'Content-Type: application/json' \
-H 'x-api-key: sk-sharely-your-api-key' \
-d '{}' | jq -r '.token')
# Get knowledge stats
curl -X GET \
'https://api.sharely.ai/v1/workspaces/{workspaceId}/knowledge/stats' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'organizationid: your-organization-id'JavaScript Example
const API_KEY = 'sk-sharely-your-api-key';
const WORKSPACE_ID = 'your-workspace-id';
const ORGANIZATION_ID = 'your-organization-id';
const API_BASE_URL = 'https://api.sharely.ai';
// Step 1: Generate access token
async function getAccessToken() {
const response = await fetch(
`${API_BASE_URL}/workspaces/${WORKSPACE_ID}/generate-access-key-token`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': API_KEY
},
body: JSON.stringify({})
}
);
const data = await response.json();
return data.token;
}
// Step 2: Get knowledge stats
async function getKnowledgeStats(accessToken) {
const response = await fetch(
`${API_BASE_URL}/v1/workspaces/${WORKSPACE_ID}/knowledge/stats`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`,
'organizationid': ORGANIZATION_ID
}
}
);
return await response.json();
}
// Usage
const accessToken = await getAccessToken();
const stats = await getKnowledgeStats(accessToken);
console.log(`Total knowledge items: ${stats.total}`);
console.log(`Processing: ${stats.byStatus.BACKGROUND_START}`);
console.log(`Failed: ${stats.byStatus.BACKGROUND_ERROR}`);
console.log(`With RBAC: ${stats.withRoles}`);Use Cases
- Dashboard metrics: Display knowledge base statistics on admin dashboards
- Processing monitoring: Track how many items are still being processed
- RBAC coverage: Monitor what percentage of knowledge has role assignments
- Error tracking: Identify and address failed processing jobs
Related Endpoints
- List Knowledge - List all knowledge items
- Get Knowledge - Get full knowledge details
- Create Knowledge - Add searchable knowledge
- Delete Knowledge - Remove knowledge from search