Create Knowledge Entry
Create knowledge entries from text, URLs, or file uploads. This unified endpoint handles all input sources with automatic processing.
How It Works
Source Types
| Source | Input | Processing | Best For |
|---|---|---|---|
text | content field | Sync (immediate) | FAQ entries, policies, short content |
url | url field | Async (returns taskId) | Web pages, help articles |
file | Multipart upload | Async (returns taskId) | PDFs, docs, manuals |
Examples by Source Type
Direct text content with immediate processing.
curl -X POST "https://platform.protobox.ai/api/v1/knowledge" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"title": "Return Policy",
"source": "text",
"content": "Our return policy allows returns within 30 days of purchase. Items must be unused and in original packaging.",
"metadata": {
"category": "policies",
"tags": ["returns", "refunds"]
}
}'const response = await fetch('https://platform.protobox.ai/api/v1/knowledge', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'Return Policy',
source: 'text',
content: 'Our return policy allows returns within 30 days...',
metadata: { category: 'policies', tags: ['returns'] }
})
});
const { data } = await response.json();
console.log('Created:', data.id);
console.log('Status:', data.processingStatus); // "completed"import requests
response = requests.post(
'https://platform.protobox.ai/api/v1/knowledge',
headers={'Authorization': f'Bearer {access_token}'},
json={
'title': 'Return Policy',
'source': 'text',
'content': 'Our return policy allows returns within 30 days...',
'metadata': {'category': 'policies'}
}
)
entry = response.json()['data']
print(f"Created: {entry['id']}, Status: {entry['processingStatus']}"){
"success": true,
"data": {
"id": "695c71705a8b2ca8d9016050",
"title": "Return Policy",
"source": "text",
"processingStatus": "completed",
"processingProgress": 100,
"content": "Our return policy allows returns within 30 days...",
"isEnabled": true,
"metadata": {
"category": "policies",
"tags": ["returns", "refunds"]
},
"createdAt": "2024-01-15T10:30:00Z"
}
}Fetch and process content from a web page.
curl -X POST "https://platform.protobox.ai/api/v1/knowledge" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"title": "Getting Started Guide",
"source": "url",
"url": "https://docs.example.com/getting-started",
"chunkingOptions": {
"chunkSizeTokens": 512,
"overlapTokens": 50
}
}'const response = await fetch('https://platform.protobox.ai/api/v1/knowledge', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'Getting Started Guide',
source: 'url',
url: 'https://docs.example.com/getting-started',
chunkingOptions: { chunkSizeTokens: 512, overlapTokens: 50 }
})
});
const { data } = await response.json();
console.log('Document ID:', data.id);
console.log('Task ID:', data.taskId); // Poll this for status
console.log('Status:', data.processingStatus); // "pending"import requests
response = requests.post(
'https://platform.protobox.ai/api/v1/knowledge',
headers={'Authorization': f'Bearer {access_token}'},
json={
'title': 'Getting Started Guide',
'source': 'url',
'url': 'https://docs.example.com/getting-started'
}
)
result = response.json()['data']
print(f"Document: {result['id']}, Task: {result['taskId']}"){
"success": true,
"data": {
"id": "695c71705a8b2ca8d9016051",
"title": "Getting Started Guide",
"source": "url",
"processingStatus": "pending",
"processingProgress": 0,
"taskId": "695c71705a8b2ca8d9016052",
"createdAt": "2024-01-15T10:30:00Z"
}
}URL Crawling Options
Crawl multiple pages from a site:
{
"source": "url",
"url": "https://docs.example.com",
"crawlOptions": {
"depth": 1, // 0=single page, 1=page+links, max 2
"maxPages": 10, // Max pages to crawl (limit: 50)
"sameDomainOnly": true
}
}Upload a file for processing.
curl -X POST "https://platform.protobox.ai/api/v1/knowledge" \
-H "Authorization: Bearer <access_token>" \
-F "file=@product-manual.pdf" \
-F "title=Product Manual" \
-F "source=file" \
-F "folderId=695c71705a8b2ca8d9016053"const formData = new FormData();
formData.append('file', fileBlob, 'product-manual.pdf');
formData.append('title', 'Product Manual');
formData.append('source', 'file');
formData.append('folderId', '695c71705a8b2ca8d9016053');
const response = await fetch('https://platform.protobox.ai/api/v1/knowledge', {
method: 'POST',
headers: { 'Authorization': `Bearer ${accessToken}` },
body: formData
});
const { data } = await response.json();
console.log('Task ID:', data.taskId);import requests
with open('product-manual.pdf', 'rb') as f:
response = requests.post(
'https://platform.protobox.ai/api/v1/knowledge',
headers={'Authorization': f'Bearer {access_token}'},
files={'file': ('product-manual.pdf', f, 'application/pdf')},
data={
'title': 'Product Manual',
'source': 'file',
'folderId': '695c71705a8b2ca8d9016053'
}
)
result = response.json()['data']
print(f"Task: {result['taskId']}"){
"success": true,
"data": {
"id": "695c71705a8b2ca8d9016054",
"title": "Product Manual",
"source": "file",
"processingStatus": "pending",
"processingProgress": 0,
"taskId": "695c71705a8b2ca8d9016055",
"createdAt": "2024-01-15T10:30:00Z"
}
}Supported file types: PDF, DOCX, TXT, HTML, MD
Polling for Async Status
For URL and file uploads, poll the task endpoint:
// Poll until complete
async function waitForProcessing(taskId) {
while (true) {
const response = await fetch(
`https://platform.protobox.ai/api/v1/knowledge/tasks/${taskId}`,
{ headers: { 'Authorization': `Bearer ${accessToken}` } }
);
const { data } = await response.json();
if (data.task.status === 'completed') {
return data.task;
}
if (data.task.status === 'failed') {
throw new Error(data.task.error);
}
await new Promise(r => setTimeout(r, 2000));
}
}Request Body
titlestringrequiredTitle of the knowledge entry. Max 500 characters.
sourcestringrequiredSource type determining how content is provided:
text- Content provided incontentfield (sync)url- Content fetched fromurlfield (async)file- Content uploaded as file (async, multipart)
Legacy values (manual, document, faq, api_docs, transcript) still supported for backwards compatibility.
contentstringThe knowledge content. Required when source="text". Max 500,000 characters.
urlstringURL to fetch content from. Required when source="url".
folderIdstringFolder ID to organize the document.
metadataobjectAdditional metadata for organization and filtering.
metadata properties
metadata.categorystringCategory for organizing entries.
metadata.tagsarrayTags for filtering.
externalReferenceIdsobjectCustomer-provided IDs for multi-tenant isolation or custom categorization.
{
"customerId": "cust_12345",
"department": "sales",
"tier": "enterprise"
}chunkingOptionsobjectCustomize document chunking for large content.
chunkingOptions properties
chunkingOptions.chunkSizeTokensnumberdefault: 1000Tokens per chunk (100-2000).
chunkingOptions.overlapTokensnumberdefault: 200Overlap between chunks (0-500).
chunkingOptions.preserveSentencesbooleandefault: truePreserve sentence boundaries when chunking.
crawlOptionsobjectURL crawling options for multi-page ingestion. Only for source="url".
crawlOptions properties
crawlOptions.depthnumberdefault: 0Crawl depth: 0=single page, 1=page+direct links, max 2.
crawlOptions.maxPagesnumberdefault: 10Maximum pages to crawl (limit: 50).
crawlOptions.sameDomainOnlybooleandefault: trueOnly follow links on the same domain.
isEnabledbooleandefault: trueWhether the entry is enabled for search.
Response
Sync Response (source=text)
| Field | Type | Description |
|---|---|---|
id | string | Document ID |
title | string | Entry title |
source | string | Source type used |
processingStatus | string | "completed" |
processingProgress | number | 100 |
content | string | Full content |
isEnabled | boolean | Search enabled |
createdAt | string | ISO 8601 timestamp |
Async Response (source=url/file)
| Field | Type | Description |
|---|---|---|
id | string | Document ID |
title | string | Entry title |
source | string | Source type used |
processingStatus | string | "pending" or "processing" |
processingProgress | number | 0-100 |
taskId | string | Task ID for polling status |
createdAt | string | ISO 8601 timestamp |
Multi-Tenant Filtering
Use externalReferenceIds to segment knowledge by customer, department, or any custom dimension:
# Create with external refs
curl -X POST "https://platform.protobox.ai/api/v1/knowledge" \
-H "Authorization: Bearer <access_token>" \
-d '{
"title": "Enterprise Pricing",
"source": "text",
"content": "Enterprise plans start at $999/month...",
"externalReferenceIds": {
"tier": "enterprise",
"region": "us-west"
}
}'
# Later, filter by external refs
curl "https://platform.protobox.ai/api/v1/knowledge?externalRef.tier=enterprise" \
-H "Authorization: Bearer <access_token>"Notes
- Text source: Processed synchronously, returns complete entry immediately
- URL/File sources: Queued for async processing, returns
taskIdto poll - Chunking: Large documents are automatically split into searchable chunks
- Embeddings: Generated using OpenAI text-embedding-3-small (1536 dimensions)
- Legacy sources:
manual,document,faqetc. still work but map totextbehavior