Protobox

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

Choose Source Processing Response source=text source=url source=file Sync Processing Async Queue Immediate Result taskId + Poll

Source Types

SourceInputProcessingBest For
textcontent fieldSync (immediate)FAQ entries, policies, short content
urlurl fieldAsync (returns taskId)Web pages, help articles
fileMultipart uploadAsync (returns taskId)PDFs, docs, manuals

Examples by Source Type

Direct text content with immediate processing.

Request
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']}")
Response
{
  "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.

Request
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']}")
Response
{
  "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.

Request
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']}")
Response
{
  "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

titlestringrequired

Title of the knowledge entry. Max 500 characters.

sourcestringrequired

Source type determining how content is provided:

  • text - Content provided in content field (sync)
  • url - Content fetched from url field (async)
  • file - Content uploaded as file (async, multipart)

Legacy values (manual, document, faq, api_docs, transcript) still supported for backwards compatibility.

contentstring

The knowledge content. Required when source="text". Max 500,000 characters.

urlstring

URL to fetch content from. Required when source="url".

folderIdstring

Folder ID to organize the document.

metadataobject

Additional metadata for organization and filtering.

metadata properties
metadata.categorystring

Category for organizing entries.

metadata.tagsarray

Tags for filtering.

externalReferenceIdsobject

Customer-provided IDs for multi-tenant isolation or custom categorization.

{
  "customerId": "cust_12345",
  "department": "sales",
  "tier": "enterprise"
}
chunkingOptionsobject

Customize document chunking for large content.

chunkingOptions properties
chunkingOptions.chunkSizeTokensnumberdefault: 1000

Tokens per chunk (100-2000).

chunkingOptions.overlapTokensnumberdefault: 200

Overlap between chunks (0-500).

chunkingOptions.preserveSentencesbooleandefault: true

Preserve sentence boundaries when chunking.

crawlOptionsobject

URL crawling options for multi-page ingestion. Only for source="url".

crawlOptions properties
crawlOptions.depthnumberdefault: 0

Crawl depth: 0=single page, 1=page+direct links, max 2.

crawlOptions.maxPagesnumberdefault: 10

Maximum pages to crawl (limit: 50).

crawlOptions.sameDomainOnlybooleandefault: true

Only follow links on the same domain.

isEnabledbooleandefault: true

Whether the entry is enabled for search.

Response

Sync Response (source=text)

FieldTypeDescription
idstringDocument ID
titlestringEntry title
sourcestringSource type used
processingStatusstring"completed"
processingProgressnumber100
contentstringFull content
isEnabledbooleanSearch enabled
createdAtstringISO 8601 timestamp

Async Response (source=url/file)

FieldTypeDescription
idstringDocument ID
titlestringEntry title
sourcestringSource type used
processingStatusstring"pending" or "processing"
processingProgressnumber0-100
taskIdstringTask ID for polling status
createdAtstringISO 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 taskId to poll
  • Chunking: Large documents are automatically split into searchable chunks
  • Embeddings: Generated using OpenAI text-embedding-3-small (1536 dimensions)
  • Legacy sources: manual, document, faq etc. still work but map to text behavior

On this page