Knowledge Base Deep-Dive

What you build: a reusable retrieval layer. This page treats the Knowledge Base as a primitive in its own right — how ingestion works, how to poll it, how retrieval is tuned, and how to run pure RAG queries from your own code (no voice or messaging turn involved). If you just want a KB attached to a support agent, start at Inbound support + KB; come here to understand the machinery.

Who it’s for: developers building BYOM agents that do their own retrieval, teams debugging “why didn’t the agent use my doc,” and anyone who wants a hosted vector-search endpoint over their content.

The two ways to use a KB

ModeRetrievalYour code
Hosted-AI agentAutomatic on every voice/messaging turn (knowledge_base_id on the agent)None
BYOM / standaloneYou call POST /v1/knowledge-bases/{id}/queryYou inject chunks into your own prompt

Step 1 — Create a KB

$curl -X POST https://api.voicebip.com/v1/knowledge-bases \
> -H "Authorization: Bearer pk_xxx" -H "Content-Type: application/json" \
> -d '{ "name": "Support FAQ", "description": "Billing, refunds, delivery" }'
1{ "id": "kb_8sd2k1fapvq3", "document_count": 0, "chunk_count": 0, "created_at": "2026-07-02T10:00:00Z" }

Step 2 — Add documents

Two source types. Files (pdf/docx/txt) use a three-step flow; URLs ingest immediately.

File upload (register → PUT → finalize)

$# 1. register — returns a presigned upload_url (valid ~10 min)
$curl -X POST https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3/documents \
> -H "Authorization: Bearer pk_xxx" -H "Content-Type: application/json" \
> -d '{ "name": "refund-policy.pdf", "source_type": "pdf", "size_bytes": 248120 }'
$# → { "id": "doc_4kq…", "status": "pending", "upload_url": "https://storage…" }
$
$# 2. PUT the bytes with the matching Content-Type
$curl -X PUT "<upload_url>" -H "Content-Type: application/pdf" \
> --data-binary @refund-policy.pdf
$
$# 3. finalize — kicks off chunk → embed → index (idempotent)
$curl -X POST https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3/documents/doc_4kq…/complete \
> -H "Authorization: Bearer pk_xxx"
source_typeContent-Type for the PUT
pdfapplication/pdf
docxapplication/vnd.openxmlformats-officedocument.wordprocessingml.document
txttext/plain

URL source (one step)

$curl -X POST https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3/documents \
> -H "Authorization: Bearer pk_xxx" -H "Content-Type: application/json" \
> -d '{ "name": "Pricing page", "source_type": "url", "source_url": "https://acme.example/pricing" }'

File uploads need object storage configured on the deployment; if it isn’t, document creation returns 503. URL sources don’t. Image-only PDFs (no text layer) can’t be extracted and end up failed.

Step 3 — Poll to ready

Ingestion is async. Only ready documents are searched:

$curl https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3/documents/doc_4kq… \
> -H "Authorization: Bearer pk_xxx"
StatusMeaning
pendingRegistered, awaiting upload + finalize (file sources)
processingExtracting text, chunking, embedding
readyIndexed and live; chunk_count populated
failederror_message says why (unreadable PDF, unreachable URL)

Step 4 — Query it (RAG without a call)

This is the standalone superpower — vector search over your content from any code path:

$curl -X POST https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3/query \
> -H "Authorization: Bearer pk_xxx" -H "Content-Type: application/json" \
> -d '{ "query": "How long do refunds take?", "top_k": 5 }'
1{
2 "query": "How long do refunds take?",
3 "count": 2,
4 "chunks": [
5 { "content": "Refunds are processed within 5–7 business days of approval…", "source": "refund-policy.pdf", "score": 0.83 },
6 { "content": "For card payments, the refund appears on your statement…", "source": "refund-policy.pdf", "score": 0.71 }
7 ]
8}
  • top_k — 1–10, default 5.
  • score — cosine similarity (0–1, higher = more relevant).
  • Below-threshold chunks are dropped, so a query with no good match returns count: 0 and 200 (not 404).
  • query is capped at 4096 characters.

Using it in a BYOM turn

1// inside your BYOM webhook handler
2const { chunks } = await fetch(
3 `https://api.voicebip.com/v1/knowledge-bases/${kbId}/query`,
4 { method: "POST",
5 headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
6 body: JSON.stringify({ query: callerMessage, top_k: 3 }) }
7).then(r => r.json());
8
9const context = chunks.map(c => c.content).join("\n---\n");
10const prompt = `Use the following context to answer.\n${context}\n\nQuestion: ${callerMessage}`;
11// → send `prompt` to your own LLM, return the reply to Voicebip

How retrieval works (and why it sometimes returns nothing)

  1. The query (or caller message) is embedded as a vector.
  2. Cosine-distance search over the KB’s ready chunks (HNSW index) finds the closest.
  3. Top top_k returned best-first, after dropping anything below the relevance threshold.
  4. Hosted agents: chunks are prepended to the system prompt. BYOM: you assemble the prompt.

For hosted agents, retrieval is fail-soft — if it errors or exceeds a 1-second budget, the agent still answers, just without KB context for that turn. The relevance gate is deliberate: injecting weakly-related passages causes more hallucination, so “no good match → no context” is the correct behaviour, not a bug.

Results are cached per (workspace, KB, query) and invalidated whenever you add, delete, or change a document — updates appear immediately.

Manage KBs and documents

$# list KBs (newest first)
$curl "https://api.voicebip.com/v1/knowledge-bases?limit=50&offset=0" -H "Authorization: Bearer pk_xxx"
$# rename
$curl -X PATCH https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3 \
> -H "Authorization: Bearer pk_xxx" -H "Content-Type: application/json" -d '{"name":"Support FAQ v2"}'
$# delete one document (removes its chunks)
$curl -X DELETE https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3/documents/doc_4kq… -H "Authorization: Bearer pk_xxx"
$# delete the whole KB (detaches from any agents referencing it)
$curl -X DELETE https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3 -H "Authorization: Bearer pk_xxx"

Limits

LimitValue
Max document size50 MiB
FormatsPDF, DOCX, TXT, URL
top_k1–10 (default 5)
Max query length4096 chars
Upload URL lifetime~10 min
Retrieval budget (hosted)~1 s, fail-soft

Dashboard & MCP

  • DashboardKnowledge section: create, drag-drop docs, watch ingestion live.
  • MCP → the MCP server exposes seven KB tools (create_knowledge_base, list_knowledge_bases, upload_knowledge_document, complete_knowledge_document, get_document_status, query_knowledge_base, attach_knowledge_base).

Next steps