> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.voicebip.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.voicebip.com/_mcp/server.

# Knowledge Base

> Give your agents grounded answers with retrieval-augmented generation (RAG) — upload documents, attach them to an agent, and Voicebip retrieves the most relevant passages on every turn.

A **Knowledge Base (KB)** lets your agents answer from your own content — product docs, policies, FAQs, price lists — instead of only what the model already knows. You upload documents, Voicebip splits them into chunks, embeds each chunk as a vector, and at answer time retrieves the most relevant passages and feeds them to the model. This is retrieval-augmented generation (RAG).

There are two ways to use a KB:

* **Hosted-AI agents** — attach a KB to the agent (`knowledge_base_id`) and retrieval happens **automatically** on every voice and messaging turn. No code on your side.
* **BYOM agents** — call the [query endpoint](#query-a-knowledge-base-byom) yourself, get back the relevant chunks, and inject them into your own LLM prompt.

## Create a Knowledge Base

```bash
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, and account questions"
  }'
```

Response:

```json
{
  "id": "kb_8sd2k1fapvq3",
  "name": "Support FAQ",
  "description": "Billing, refunds, and account questions",
  "document_count": 0,
  "chunk_count": 0,
  "created_at": "2026-06-22T10:00:00Z",
  "updated_at": "2026-06-22T10:00:00Z"
}
```

`document_count` and `chunk_count` are recomputed as documents are ingested and deleted.

## Add documents

A KB is only useful once it has documents. There are two source types:

* **File uploads** (`pdf`, `docx`, `txt`) — a two-step flow: register the document, upload the bytes, then finalize.
* **URLs** (`url`) — Voicebip fetches the page and extracts its text; ingestion starts immediately.

Supported formats: **PDF, DOCX, TXT, and URL**. Max file size is **50 MiB**. (PDFs need a real text layer — image-only scans without OCR won't extract.)

### Upload a file (two-step)

**Step 1 — register the document.** You get back a short-lived presigned `upload_url` (valid \~10 minutes):

```bash
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
  }'
```

```json
{
  "id": "doc_4kq9zr1m7w0c",
  "knowledge_base_id": "kb_8sd2k1fapvq3",
  "name": "refund-policy.pdf",
  "source_type": "pdf",
  "status": "pending",
  "chunk_count": 0,
  "size_bytes": 248120,
  "created_at": "2026-06-22T10:01:00Z",
  "updated_at": "2026-06-22T10:01:00Z",
  "upload_url": "https://storage.voicebip.com/...&X-Amz-Signature=..."
}
```

**Step 2 — PUT the bytes** to `upload_url` with a `Content-Type` matching the source type:

| source_type | Content-Type                                                              |
| ----------- | ------------------------------------------------------------------------- |
| `pdf`       | `application/pdf`                                                         |
| `docx`      | `application/vnd.openxmlformats-officedocument.wordprocessingml.document` |
| `txt`       | `text/plain`                                                              |

```bash
curl -X PUT "<upload_url>" \
  -H "Content-Type: application/pdf" \
  --data-binary @refund-policy.pdf
```

**Step 3 — finalize.** This verifies the upload landed and kicks off processing (chunk → embed → index):

```bash
curl -X POST https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3/documents/doc_4kq9zr1m7w0c/complete \
  -H "Authorization: Bearer pk_xxx"
```

The document status moves to `processing`. Finalize is idempotent — re-calling it on an already-`ready` document does nothing (no duplicate embedding charges). If you register a document but never finalize it, an automatic reaper cleans up the abandoned upload.

> **Note**
>
> File uploads require object storage to be configured on the deployment. If it isn't, document creation returns `503`. URL sources don't need storage.

### Add a URL

For a URL, pass `source_type: "url"` and `source_url`. There's no upload step — ingestion begins right away:

```bash
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://example.com/pricing"
  }'
```

## Track ingestion status

Processing is asynchronous. Poll the document until it's `ready`:

```bash
curl https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3/documents/doc_4kq9zr1m7w0c \
  -H "Authorization: Bearer pk_xxx"
```

`status` moves through:

| Status       | Meaning                                                                                              |
| ------------ | ---------------------------------------------------------------------------------------------------- |
| `pending`    | Registered, waiting for upload + finalize (file sources).                                            |
| `processing` | Extracting text, chunking, and embedding.                                                            |
| `ready`      | Indexed and live for retrieval. `chunk_count` is populated.                                          |
| `failed`     | Extraction or embedding failed. `error_message` explains why (e.g. unreadable PDF, unreachable URL). |

Only `ready` documents are searched. A document with no extractable text (e.g. an image-only PDF) ends up `failed`.

## Use with a hosted-AI agent

Attach the KB to the agent and retrieval is automatic — nothing else to build:

```bash
curl -X PATCH https://api.voicebip.com/v1/agents/agt_PAEZ_njcfm2kycpjs \
  -H "Authorization: Bearer pk_xxx" \
  -H "Content-Type: application/json" \
  -d '{"knowledge_base_id": "kb_8sd2k1fapvq3"}'
```

On every voice and messaging turn, Voicebip embeds the caller's message, retrieves the most relevant chunks from the attached KB, and prepends them to the agent's `system_prompt` before calling the model. Many agents can share one KB. Send an empty string (`""`) to detach.

Retrieval is **fail-soft**: if it errors or times out (1 second budget), the agent still answers — just without KB context for that turn. A **relevance gate** also applies: if nothing in the KB is similar enough to the question, no context is injected (low-relevance passages cause more hallucination than they prevent).

## Query a knowledge base (BYOM)

BYOM agents run their own model, so retrieval isn't automatic. Call the query endpoint to get the relevant chunks, then inject them into your prompt yourself:

```bash
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
  }'
```

```json
{
  "query": "How long do refunds take?",
  "count": 2,
  "chunks": [
    {
      "content": "Refunds are processed within 5–7 business days of approval...",
      "source": "refund-policy.pdf",
      "score": 0.83
    },
    {
      "content": "For card payments, the refund appears on your statement...",
      "source": "refund-policy.pdf",
      "score": 0.71
    }
  ]
}
```

* `top_k` (1–10, default 5) caps how many chunks come back.
* `score` is cosine similarity (0–1, higher is more relevant). Chunks below the relevance threshold are filtered out, so a query with no good match returns `count: 0` and an empty list (HTTP `200`, not `404`).
* `query` is capped at 4096 characters.

A typical BYOM turn: call `/query` with the caller's message, take the returned `content` blocks, and prepend them to the prompt you send your LLM (e.g. "Use the following context to answer: …").

## Manage knowledge bases and documents

```bash
# List your knowledge bases (newest first)
curl "https://api.voicebip.com/v1/knowledge-bases?limit=50&offset=0" \
  -H "Authorization: Bearer pk_xxx"

# Get one
curl https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3 \
  -H "Authorization: Bearer pk_xxx"

# Rename / re-describe
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)"}'

# List documents in a KB
curl https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3/documents \
  -H "Authorization: Bearer pk_xxx"

# Delete a single document (removes its chunks too)
curl -X DELETE https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3/documents/doc_4kq9zr1m7w0c \
  -H "Authorization: Bearer pk_xxx"

# Delete the whole knowledge base
curl -X DELETE https://api.voicebip.com/v1/knowledge-bases/kb_8sd2k1fapvq3 \
  -H "Authorization: Bearer pk_xxx"
```

Deleting a KB detaches it from any agents that referenced it (those agents fall back to no KB). Deletes return `204 No Content`.

## How retrieval works

1. The caller's message (hosted) or your `query` (BYOM) is embedded as a vector.
2. A vector similarity search (cosine distance, HNSW index) finds the closest chunks across the KB's `ready` documents.
3. The top `top_k` chunks are returned best-first, after dropping anything below the relevance threshold.
4. For hosted agents, those chunks are formatted and prepended to the system prompt; for BYOM you do the prompt assembly.

Results are briefly cached per (workspace, KB, query) and the cache is invalidated whenever you add, delete, or change a document — so updates show up right away.

## Limits

| Limit               | Value               |
| ------------------- | ------------------- |
| Max document size   | 50 MiB              |
| Supported formats   | PDF, DOCX, TXT, URL |
| `top_k` per query   | 1–10 (default 5)    |
| Max query length    | 4096 characters     |
| Upload URL lifetime | \~10 minutes        |

## Dashboard & MCP

* **Dashboard** — manage knowledge bases under the **Knowledge** section: create a KB, drag-and-drop documents, and watch ingestion status update live.
* **MCP** — the [MCP server](/integrations/mcp/overview) exposes KB tools (`create_knowledge_base`, `list_knowledge_bases`, `upload_knowledge_document`, `complete_knowledge_document`, `get_document_status`, `query_knowledge_base`, `attach_knowledge_base`) so AI coding agents can build and query knowledge bases directly.