Protobox

Knowledge Base

Ingest documents and search with hybrid queries using @protoboxai/sdk

The knowledge module ingests documents and searches them with hybrid vector+text queries. Protobox handles chunking, embedding, and retrieval, so you don't build a RAG pipeline from scratch.

Installation

npm install @protoboxai/sdk

Setup

import { ProtoboxSDK } from '@protoboxai/sdk';

const client = new ProtoboxSDK({
  baseUrl: 'https://platform.protobox.ai',
  apiKey: process.env.PROTOBOX_API_KEY,
});

Every method returns an ApiResponse<T> — check res.success and read res.data.

Create an entry

There are three source types. Text entries process synchronously; URL entries process asynchronously and return a taskId you can poll.

Text entry (sync)

const res = await client.knowledge.create({
  title: 'Return Policy',
  source: 'text',
  content: 'Returns accepted within 30 days of purchase. Items must be unused.',
  metadata: { category: 'policies', tags: ['returns'] },
});

const entry = res.data!;
console.log('Created:', entry.id, entry.processingStatus);

URL entry (async)

const res = await client.knowledge.create({
  title: 'Help Center Article',
  source: 'url',
  url: 'https://help.example.com/getting-started',
  crawlOptions: { depth: 1, maxPages: 10, sameDomainOnly: true },
});

const entry = res.data!;
console.log('Task ID:', entry.taskId); // poll for status

CreateKnowledgeData fields:

FieldTypeRequiredDescription
titlestringYesEntry title
source'text' | 'url' | 'file'YesSource type
contentstringFor textDocument content
urlstringFor urlWeb page URL
folderIdstringNoFolder to place the entry in
metadataobjectNo{ category?, tags?, ... }
chunkingOptionsobjectNo{ chunkSizeTokens?, overlapTokens? }
crawlOptionsobjectNo{ depth?, maxPages?, sameDomainOnly? }

File upload (async)

import fs from 'fs';

const res = await client.knowledge.createFromFile(
  fs.readFileSync('./product-manual.pdf'),
  'product-manual.pdf',
  { title: 'Product Manual', metadata: { tags: ['manual'] } },
);

console.log('Task ID:', res.data!.taskId);
const res = await client.knowledge.search({
  query: 'What is your return policy for electronics?',
  mode: 'hybrid', // 'hybrid' | 'vector' | 'text'
  limit: 5,
  minScore: 0.7,
});

res.data!.results.forEach((r) => {
  console.log(`[${r.score.toFixed(2)}] ${r.title}`);
  console.log(`  ${r.content.slice(0, 100)}...`);
});

SearchKnowledgeData fields: query (required), mode, limit, minScore, externalReferenceIds. Returns a SearchResponse with results, query, mode, and totalResults.

ModeBest for
hybrid (default)Most queries — semantic + keyword
vectorConceptual questions where keywords differ
textSpecific terms, codes, identifiers

List and filter

const res = await client.knowledge.list({
  source: 'url',
  processingStatus: 'completed',
  folderId: 'folder_123',
  page: 1,
  limit: 20,
});

res.data!.items.forEach((entry) => {
  console.log(`${entry.title} (${entry.source}) — ${entry.processingStatus}`);
});

KnowledgeFilters: search, source, folderId, isEnabled, processingStatus, page, limit.

Get, update, delete

// Get entry details
const got = await client.knowledge.get('kb_abc123');
console.log('Chunks:', got.data!.chunkCount);

// Update (text content, title, metadata, enabled state)
await client.knowledge.update('kb_abc123', {
  title: 'Updated Return Policy',
  metadata: { tags: ['returns', '2026'] },
});

// Delete
await client.knowledge.delete('kb_abc123');

Processing status & chunks

// Poll an async task (URL/file ingestion)
const task = await client.knowledge.getTaskStatus('task_abc123');
console.log('Status:', task.data!.status, 'Progress:', task.data!.progress);

// Inspect the chunks generated for an entry
const chunks = await client.knowledge.getChunks('kb_abc123');
console.log('Chunk count:', chunks.data!.length);

Full example

import { ProtoboxSDK } from '@protoboxai/sdk';

const client = new ProtoboxSDK({
  baseUrl: 'https://platform.protobox.ai',
  apiKey: process.env.PROTOBOX_API_KEY,
});

class SupportKB {
  constructor(private client: ProtoboxSDK) {}

  async findAnswer(question: string): Promise<string | null> {
    const res = await this.client.knowledge.search({
      query: question,
      mode: 'hybrid',
      limit: 3,
      minScore: 0.75,
    });
    const results = res.data?.results ?? [];
    return results.length > 0 ? results[0].content : null;
  }

  async addFAQ(question: string, answer: string) {
    return this.client.knowledge.create({
      title: question,
      source: 'text',
      content: answer,
      metadata: { tags: ['faq'] },
    });
  }
}

const kb = new SupportKB(client);
const answer = await kb.findAnswer('How do I track my order?');
console.log(answer ?? 'No relevant answer found');

Types

import type {
  Knowledge,
  KnowledgeChunk,
  KnowledgeFilters,
  CreateKnowledgeData,
  UpdateKnowledgeData,
  SearchKnowledgeData,
  SearchResponse,
  SearchResult,
} from '@protoboxai/sdk';

Next steps

On this page