Update Metadata
Update custom metadata fields for a knowledge item. This endpoint allows you to add, update, or remove custom metadata properties while keeping the content and reserved fields unchanged.
Endpoint
PUT /v1/workspaces/{workspaceId}/knowledge/{knowledgeId}/metadataAuthentication
Requires Bearer token authentication. See Authentication for details.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string (UUID) | Yes | The ID of your workspace |
knowledgeId | string (UUID) | Yes | The ID of the knowledge item to update |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Knowledge type: URL, FILE, LINK, STRING, WEBSITE, or ELASTICSEARCH_INDEX. Must match the item's actual type. |
metadata | object | Yes | Custom metadata as key-value pairs. Values must be strings or numbers only. |
removeMetadataKeys | array of strings | No | Array of metadata keys to remove |
Metadata Value Constraints
Important: Metadata values can only be strings or numbers. Nested objects, arrays, booleans, or null values are not allowed.
// Valid metadata
{
"metadata": {
"department": "Engineering",
"version": "2.0",
"priority": 5,
"reviewedBy": "John Doe"
}
}
// Invalid metadata - will be rejected
{
"metadata": {
"settings": {"nested": "object"}, // ❌ No nested objects
"tags": ["tag1", "tag2"], // ❌ No arrays
"active": true, // ❌ No booleans
"deletedAt": null // ❌ No null values
}
}Reserved Field Restrictions
The following fields cannot be updated via this endpoint:
title- Use the Update Reserved Fields endpointlanguage- Use the Update Reserved Fields endpoint
Attempting to update these fields will result in an error.
Response
Success Response
Status Code: 200 OK
Headers:
X-API-Version: v1Body:
{
"knowledgeId": "550e8400-e29b-41d4-a716-446655440000"
}Examples
Add Custom Metadata
Add custom metadata fields to a knowledge item:
curl -X PUT \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/knowledge/123e4567-e89b-12d3-a456-426614174000/metadata' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"type": "FILE",
"metadata": {
"department": "Engineering",
"version": "2.1",
"reviewedBy": "Jane Doe",
"priority": 3
}
}'Response:
{
"knowledgeId": "123e4567-e89b-12d3-a456-426614174000"
}Update Existing Metadata
Update specific metadata fields while preserving others:
curl -X PUT \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/knowledge/123e4567-e89b-12d3-a456-426614174000/metadata' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"type": "FILE",
"metadata": {
"version": "2.2",
"lastUpdated": "2025-01-16"
}
}'Remove Metadata Fields
Remove specific metadata fields using removeMetadataKeys:
curl -X PUT \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/knowledge/123e4567-e89b-12d3-a456-426614174000/metadata' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"type": "FILE",
"metadata": {},
"removeMetadataKeys": ["oldField", "deprecatedField"]
}'Add and Remove Metadata Simultaneously
You can add new metadata and remove old fields in a single request:
curl -X PUT \
'https://api.sharely.ai/v1/workspaces/your-workspace-id/knowledge/123e4567-e89b-12d3-a456-426614174000/metadata' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"type": "URL",
"metadata": {
"category": "Documentation",
"updatedAt": "2025-01-16"
},
"removeMetadataKeys": ["oldCategory", "tempField"]
}'JavaScript Example
const API_KEY = 'YOUR_API_KEY';
const WORKSPACE_ID = 'your-workspace-id';
const BASE_URL = 'https://api.sharely.ai/v1';
async function updateMetadata(knowledgeId, type, metadata, removeKeys = null) {
const body = {
type: type,
metadata: metadata
};
if (removeKeys && removeKeys.length > 0) {
body.removeMetadataKeys = removeKeys;
}
const response = await fetch(
`${BASE_URL}/workspaces/${WORKSPACE_ID}/knowledge/${knowledgeId}/metadata`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}
);
if (!response.ok) {
throw new Error(`Update failed: ${response.statusText}`);
}
return await response.json();
}
// Usage - Add metadata
try {
const result = await updateMetadata(
'123e4567-e89b-12d3-a456-426614174000',
'FILE',
{
department: 'Engineering',
version: '2.1',
priority: 5
}
);
console.log('Metadata updated:', result.knowledgeId);
} catch (error) {
console.error('Update failed:', error.message);
}
// Usage - Add and remove metadata
try {
const result = await updateMetadata(
'123e4567-e89b-12d3-a456-426614174000',
'FILE',
{
newField: 'newValue',
updatedAt: '2025-01-16'
},
['oldField', 'deprecatedField']
);
console.log('Metadata updated:', result.knowledgeId);
} catch (error) {
console.error('Update failed:', error.message);
}Python Example
import requests
import json
API_KEY = 'YOUR_API_KEY'
WORKSPACE_ID = 'your-workspace-id'
BASE_URL = 'https://api.sharely.ai/v1'
def update_metadata(knowledge_id, knowledge_type, metadata, remove_keys=None):
payload = {
'type': knowledge_type,
'metadata': metadata
}
if remove_keys:
payload['removeMetadataKeys'] = remove_keys
response = requests.put(
f'{BASE_URL}/workspaces/{WORKSPACE_ID}/knowledge/{knowledge_id}/metadata',
headers={
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
},
json=payload
)
response.raise_for_status()
return response.json()
# Usage - Add metadata
try:
result = update_metadata(
'123e4567-e89b-12d3-a456-426614174000',
'FILE',
{
'department': 'Engineering',
'version': '2.1',
'priority': 5
}
)
print(f"Metadata updated: {result['knowledgeId']}")
except requests.exceptions.HTTPError as error:
print(f"Update failed: {error}")
# Usage - Add and remove metadata
try:
result = update_metadata(
'123e4567-e89b-12d3-a456-426614174000',
'FILE',
{
'newField': 'newValue',
'updatedAt': '2025-01-16'
},
['oldField', 'deprecatedField']
)
print(f"Metadata updated: {result['knowledgeId']}")
except requests.exceptions.HTTPError as error:
print(f"Update failed: {error}")Error Responses
400 Bad Request
Missing required fields:
{
"error": "Bad Request",
"message": "Missing required field: metadata"
}Invalid metadata values (nested objects):
{
"error": "Bad Request",
"message": "Metadata values must be strings or numbers only, nested objects are not allowed"
}Attempting to update reserved fields:
{
"error": "Bad Request",
"message": "Title cannot be updated with this endpoint, use the reserved fields endpoint"
}{
"error": "Bad Request",
"message": "Language cannot be updated with this endpoint, use the reserved fields endpoint"
}401 Unauthorized
Invalid or missing API key:
{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}403 Forbidden
Knowledge not in completed status:
{
"error": "Forbidden",
"message": "Knowledge with ID {knowledgeId} is not in completed status"
}404 Not Found
Knowledge item doesn't exist:
{
"error": "Not Found",
"message": "Knowledge with ID {knowledgeId} not found"
}422 Unprocessable Entity
Type mismatch:
{
"error": "Unprocessable Entity",
"message": "Type mismatch"
}500 Internal Server Error
Server error during update:
{
"error": "Internal Server Error",
"message": "Failed to update metadata"
}Use Cases
Tag Content by Department
Add organizational metadata to knowledge items:
await updateMetadata(
knowledgeId,
'FILE',
{
department: 'Sales',
region: 'North America',
accessLevel: '2'
}
);Track Document Versions
Maintain version tracking in metadata:
await updateMetadata(
knowledgeId,
'FILE',
{
version: '3.0',
versionDate: '2025-01-16',
changedBy: 'Jane Doe'
}
);Add Review Information
Track review status and reviewers:
await updateMetadata(
knowledgeId,
'URL',
{
reviewStatus: 'approved',
reviewedBy: 'John Smith',
reviewDate: '2025-01-16',
nextReviewDate: '2025-04-16'
}
);Clean Up Old Metadata
Remove deprecated or temporary metadata fields:
await updateMetadata(
knowledgeId,
'FILE',
{},
['tempField', 'deprecatedCategory', 'oldVersion']
);Batch Update Metadata
Update metadata for multiple knowledge items:
async function batchUpdateMetadata(updates) {
const results = [];
for (const { knowledgeId, type, metadata } of updates) {
try {
const result = await updateMetadata(knowledgeId, type, metadata);
results.push({ success: true, knowledgeId, result });
} catch (error) {
results.push({ success: false, knowledgeId, error: error.message });
}
}
return results;
}
// Usage
const updates = [
{
knowledgeId: 'knowledge-1',
type: 'FILE',
metadata: { department: 'Engineering', version: '2.0' }
},
{
knowledgeId: 'knowledge-2',
type: 'URL',
metadata: { category: 'Documentation', priority: 5 }
}
];
const results = await batchUpdateMetadata(updates);Important Notes
Metadata Merging
Metadata is merged with existing metadata, not replaced:
Existing metadata:
{
"department": "Sales",
"version": "1.0"
}Update request:
{
"metadata": {
"version": "2.0",
"priority": 5
}
}Result:
{
"department": "Sales",
"version": "2.0",
"priority": 5
}Type Validation
The type parameter must match the knowledge item's actual type. The API validates this to prevent accidental updates to the wrong item.
Status Requirement
Knowledge items must be in COMPLETED status to update metadata. Items that are still processing cannot be updated.
Reserved Fields
To update title or language, use the Update Reserved Fields endpoint instead. These fields are considered core properties and require special handling.
Vector Database Updates
When you update metadata, the changes are propagated to the vector database (Pinecone) to ensure search results reflect the updated metadata.
Best Practices
Use Consistent Key Names
Establish standard metadata key names across your organization:
// Good - consistent naming
await updateMetadata(knowledgeId, 'FILE', {
department: 'Engineering',
reviewedBy: 'Jane Doe',
reviewDate: '2025-01-16'
});
// Avoid - inconsistent naming
await updateMetadata(knowledgeId, 'FILE', {
dept: 'Engineering', // Inconsistent abbreviation
reviewer: 'Jane Doe', // Different naming pattern
review_date: '2025-01-16' // Snake case vs camelCase
});Validate Type Before Updating
Always verify the knowledge type before updating:
const knowledge = await getKnowledge(knowledgeId);
await updateMetadata(
knowledgeId,
knowledge.type, // Use actual type
metadata
);Handle Errors Gracefully
Check for common error conditions:
try {
await updateMetadata(knowledgeId, 'FILE', metadata);
} catch (error) {
if (error.status === 403) {
console.error('Knowledge not in completed status');
} else if (error.status === 422) {
console.error('Type mismatch - verify knowledge type');
} else if (error.status === 400) {
console.error('Invalid metadata format or reserved field');
} else {
console.error('Update failed:', error.message);
}
}Remove Metadata Carefully
Verify keys exist before removing:
const knowledge = await getKnowledge(knowledgeId);
const keysToRemove = ['oldField', 'deprecatedField'].filter(key =>
knowledge.metadata.hasOwnProperty(key)
);
if (keysToRemove.length > 0) {
await updateMetadata(knowledgeId, knowledge.type, {}, keysToRemove);
}Related Endpoints
- Update Reserved Fields - Update title and language
- Get Knowledge - Retrieve current metadata
- Create Knowledge - Create knowledge with metadata
- Search Knowledge - Search using metadata