Skip to main content

Knowledge Hub Management

Ingest, organize, and query your tenant-specific knowledge base so AI agents can answer questions using your own documents.

What Is the Knowledge Hub?

The Knowledge Hub is a tenant-scoped RAG (Retrieval-Augmented Generation) knowledge base. Each tenant maintains a private collection of documents that are chunked, embedded, and indexed for semantic search and AI-powered answer generation.

Key properties:

  • Tenant-isolated -- every document, chunk, and index is scoped to a single tenant. Cross-tenant data leakage is prevented at the API, data model, and vector store layers.
  • Multi-format -- supports Markdown, PDF, support tickets, FAQs, troubleshooting guides, release notes, video transcripts, and general articles.
  • Hybrid search -- combines vector similarity search with keyword (BM25-style) matching via Reciprocal Rank Fusion for the best recall.
  • AI answers with citations -- an LLM reads the most relevant chunks and generates a sourced answer with confidence scoring.

All endpoints live under /api/v1/knowledge-base and require a valid JWT Bearer token.


Supported Document Types

TypeEnum ValueBest For
MarkdownmarkdownStructured docs with headers (default)
PDFpdfScanned manuals, uploaded files
Support Ticketsupport_ticketResolved issue/resolution pairs
FAQfaqShort-answer knowledge
TroubleshootingtroubleshootingStep-by-step resolution guides
ArticlearticleGeneral knowledge content
Release Notesrelease_notesVersion-tagged product updates
Video Transcriptvideo_transcriptRaw transcription output

Ingesting Documents

Ingest a Text Document

Send the document content directly in the request body. This is the most common path for Markdown, articles, FAQs, and other text-based content.

curl -X POST https://dev.api.olympuscloud.ai/v1/knowledge-base/ingest \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "550e8400-e29b-41d4-a716-446655449100",
"title": "Opening Procedures",
"content": "# Opening Procedures\n\nArrive 30 minutes before doors open...",
"doc_type": "markdown",
"category": "operations",
"tags": ["sop", "opening"],
"source_url": "https://wiki.example.com/sop/opening",
"chunking_strategy": "semantic"
}'

Response (HTTP 201):

{
"document_id": "a1b2c3d4-...",
"status": "success",
"chunks_created": 6,
"chunks_indexed": 6,
"processing_time_ms": 320,
"error_message": null
}

Field reference:

FieldTypeDescription
tenant_idstringRequired. Owning tenant ID.
titlestringRequired. Human-readable document title.
contentstringRequired. Full document text.
doc_typestringOne of the supported document types. Default: markdown.
categorystringOptional grouping label (e.g., operations, hr, menu).
tagsarrayOptional list of tags for filtering.
source_urlstringOptional URL pointing to the original source.
chunking_strategystringsemantic (default), fixed, or paragraph.

Ingest a PDF

Upload a PDF file using multipart form data. The title and tenant ID are passed as query parameters.

curl -X POST \
"https://dev.api.olympuscloud.ai/v1/knowledge-base/ingest/pdf?tenant_id=550e8400-e29b-41d4-a716-446655449100&title=Safety%20Manual&category=compliance" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@safety-manual.pdf"

The file must have a .pdf extension. Text is extracted from all pages before chunking and indexing.

Ingest a Resolved Support Ticket

Resolved support tickets can be turned into searchable knowledge articles. Provide the issue description and its resolution separately -- the service formats them into a single knowledge document.

curl -X POST https://dev.api.olympuscloud.ai/v1/knowledge-base/ingest/support-ticket \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "550e8400-e29b-41d4-a716-446655449100",
"title": "POS Not Printing Receipts",
"issue": "Receipts stopped printing after the latest firmware update.",
"resolution": "Reset the print spooler service and re-pair the Bluetooth connection.",
"category": "hardware",
"tags": ["printer", "pos", "bluetooth"]
}'

Bulk Ingest

Ingest multiple documents in a single request. Each document in the array follows the same schema as the single-document ingest endpoint.

curl -X POST https://dev.api.olympuscloud.ai/v1/knowledge-base/ingest/bulk \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "550e8400-e29b-41d4-a716-446655449100",
"documents": [
{
"title": "Closing Procedures",
"content": "# Closing Procedures\n\nBegin 15 minutes before close...",
"doc_type": "article",
"category": "operations",
"tags": ["sop", "closing"]
},
{
"title": "Allergy Handling",
"content": "# Allergy Handling\n\nAlways ask guests about allergies...",
"doc_type": "article",
"category": "safety",
"tags": ["allergy", "compliance"]
}
]
}'

Response:

{
"total": 2,
"success": 2,
"failed": 0,
"results": [
{ "document_id": "abc-123", "status": "success", "title": "Closing Procedures" },
{ "document_id": "def-456", "status": "success", "title": "Allergy Handling" }
]
}

Failed documents include an error field in their result entry. The endpoint processes all documents regardless of individual failures, so you always get a complete report.


How Documents Get Indexed

After ingestion, every document passes through a pipeline before it becomes queryable:

  1. Content extraction -- format-specific processing (Markdown frontmatter stripping, PDF text extraction, transcript cleanup).
  2. Content hashing -- a SHA-256 hash is stored for change detection.
  3. Chunking -- the document is split into chunks according to the chosen strategy.
  4. Embedding -- each chunk is embedded into a 768-dimensional vector using Workers AI (BGE Base model).
  5. Indexing -- vectors are upserted into the tenant's Cloudflare Vectorize index, and a parallel keyword index is built for BM25-style retrieval.

Chunking Strategies

StrategyDescriptionBest For
semantic (default)Splits on Markdown headers and paragraph boundariesStructured documents with sections
fixedFixed-size character window with overlapUnstructured text, transcripts
paragraphSplits on double newlinesSimple articles, short docs
tip

Use the default semantic strategy for most documents. Switch to fixed for raw transcripts or unstructured text that lacks headers.


Managing Documents

List Documents

Retrieve a paginated list of documents for a tenant. Filter by category or document type.

curl -X GET \
"https://dev.api.olympuscloud.ai/v1/knowledge-base/documents?tenant_id=TENANT_ID&category=operations&limit=20&offset=0" \
-H "Authorization: Bearer $TOKEN"

Query parameters:

ParameterTypeDefaultDescription
tenant_idstringrequiredTenant ID
categorystring--Filter by category
doc_typestring--Filter by document type enum value
limitinteger50Results per page (1--200)
offsetinteger0Pagination offset

Get Document Details

curl -X GET https://dev.api.olympuscloud.ai/v1/knowledge-base/documents/{document_id} \
-H "Authorization: Bearer $TOKEN"

Returns the full document metadata including title, type, category, tags, status, chunk count, word count, source URL, and timestamps.

Delete a Document

curl -X DELETE https://dev.api.olympuscloud.ai/v1/knowledge-base/documents/{document_id} \
-H "Authorization: Bearer $TOKEN"

Returns HTTP 204 on success. Deleting a document removes it from both the vector index and the keyword index. All associated chunks are cascade-deleted.


Searching the Knowledge Base

Search returns the most relevant chunks across all of a tenant's documents. Three search methods are available:

MethodDescription
hybrid (default)Combines vector and keyword search via Reciprocal Rank Fusion -- best overall recall
vectorPure semantic similarity via Vectorize embeddings
keywordBM25-style term matching -- good for exact names, codes, product IDs
curl -X POST https://dev.api.olympuscloud.ai/v1/knowledge-base/search \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "What is the dress code policy?",
"tenant_id": "550e8400-e29b-41d4-a716-446655449100",
"top_k": 5,
"category": "hr",
"search_method": "hybrid"
}'

Search parameters:

ParameterTypeDefaultDescription
querystringrequiredNatural-language search query
tenant_idstringrequiredTenant scope
top_kinteger5Number of results (1--20)
categorystring--Filter by category
doc_typesarray--Filter by document type values
search_methodstringhybridvector, keyword, or hybrid

Each result includes the matching chunk content, a relevance score, the parent document title, the section title (if available), and which search method produced the match.

AI-Generated Answers

For a complete answer with source citations instead of raw chunks, use the answer endpoint:

curl -X POST https://dev.api.olympuscloud.ai/v1/knowledge-base/answer \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"question": "What should I wear to work?",
"tenant_id": "550e8400-e29b-41d4-a716-446655449100",
"top_k": 5,
"category": "hr"
}'

The response includes:

FieldDescription
answerLLM-generated answer referencing source documents
confidenceModel confidence score (0--1)
sourcesCited documents with title, section, URL, and relevance score
has_direct_answerWhether the knowledge base contained a clear answer
needs_human_reviewFlag indicating low confidence or ambiguous results
model_tierACP tier used for generation (e.g., T3)
generation_latency_msTime spent generating the answer
search_latency_msTime spent retrieving context
note

When needs_human_review is true, the answer may be incomplete or uncertain. Surface this flag in your UI to prompt a human follow-up.


Monitoring Usage

Knowledge Base Statistics

Track document counts, indexing status, and content distribution for a tenant:

curl -X GET \
"https://dev.api.olympuscloud.ai/v1/knowledge-base/stats?tenant_id=TENANT_ID" \
-H "Authorization: Bearer $TOKEN"

Response:

{
"tenant_id": "550e8400-e29b-41d4-a716-446655449100",
"total_documents": 47,
"total_chunks": 312,
"total_words": 89450,
"documents_by_type": {
"markdown": 20,
"pdf": 12,
"support_ticket": 10,
"faq": 5
},
"documents_by_category": {
"operations": 15,
"menu": 12,
"training": 10,
"policies": 7,
"uncategorized": 3
},
"indexed_documents": 45,
"pending_documents": 2
}

Use the pending_documents count to verify that all ingested documents have finished processing. A non-zero value means some documents are still being chunked or embedded.


Endpoint Summary

MethodPathPurpose
GET/knowledge-base/healthService health check
POST/knowledge-base/ingestIngest a text document
POST/knowledge-base/ingest/pdfUpload and ingest a PDF
POST/knowledge-base/ingest/support-ticketIngest a resolved support ticket
POST/knowledge-base/ingest/bulkBulk ingest multiple documents
POST/knowledge-base/searchSearch with hybrid/vector/keyword
POST/knowledge-base/answerGenerate an AI answer with citations
GET/knowledge-base/documentsList documents (paginated, filterable)
GET/knowledge-base/documents/{id}Get document details
DELETE/knowledge-base/documents/{id}Delete a document and its chunks
GET/knowledge-base/statsTenant usage statistics