> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pyai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Knowledge bases: ground your agent in your content

> Create a hosted knowledge base, add documents (file, URL, pasted text, or a website crawl), and bind it to an Omni agent or your org defaults, so agents answer from your content with no retrieval server of your own.

An **Omni knowledge base** is hosted grounding: you add content once, and every
bound agent retrieves from it per turn while it talks. Paste text, upload a
file, add a URL, or crawl a public website. No vector database, no retrieval
server, no `kb_endpoint` to host. (If you already run your own retrieval, the
[`kb_endpoint`](/guides/omni-tools) configure knob stays supported; this
guide is the hosted path.)

You need a key with the `kb:manage` scope (create one in the
[console](https://console.pyai.com); sandbox keys don't carry it).

## Step 1, create a knowledge base

```bash theme={null}
curl -X POST https://api.pyai.com/v1/knowledgebases \
  -H "Authorization: Bearer $PYAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Support KB"}'
# -> { "id": "kb_...", "name": "Support KB", "status": "active", ... }
```

Names are unique per organization (case-insensitive), so the console picker
stays unambiguous.

## Step 2, add content

Four ways. File, URL, and pasted text share `/documents`. A public website
uses `/crawls`, which discovers same-origin pages and registers each one as a
normal URL document. Content registers as `pending` and is chunked and
embedded asynchronously; poll `status` until it reads `indexed`. Do not treat
the site as ready while pages are still `pending`.

**Paste text** (policies, FAQs, snippets):

```bash theme={null}
curl -X POST https://api.pyai.com/v1/knowledgebases/kb_.../documents \
  -H "Authorization: Bearer $PYAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Our refund policy allows returns within thirty days..."}'
```

**Fetch a URL** (one help-center page):

```bash theme={null}
curl -X POST https://api.pyai.com/v1/knowledgebases/kb_.../documents \
  -H "Authorization: Bearer $PYAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://your-site.com/refund-policy"}'
```

**Crawl a public website** (sitemap, then a shallow same-origin walk; default
25 pages, hard cap 40). Private, loopback, and metadata addresses are
rejected. Already-ingested URLs in this base are reused:

```bash theme={null}
curl -X POST https://api.pyai.com/v1/knowledgebases/kb_.../crawls \
  -H "Authorization: Bearer $PYAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://your-site.com", "max_pages": 25}'
```

**Upload a file** (pdf, docx, xlsx, txt, md, csv, html, json; 25MB max):

```bash theme={null}
curl -X POST https://api.pyai.com/v1/knowledgebases/kb_.../documents \
  -H "Authorization: Bearer $PYAI_API_KEY" \
  -F file=@returns-policy.pdf -F title="Returns policy"
```

Verify what the agent will actually retrieve with
`GET /v1/knowledgebases/{id}/documents/{docId}/content`, which returns the
extracted text and indexed chunks. Pasted-text documents can be edited in place
(`PATCH .../documents/{docId}`); re-add files or URLs to replace them. A
`failed` document can be re-queued with `POST .../documents/{docId}/retry`.

## Step 3, bind it to your agents

**Per agent profile** (sessions opened with `session_label=<agent_id>` ground
against these):

```bash theme={null}
curl -X PUT https://api.pyai.com/v1/agents/agent_.../knowledgebases \
  -H "Authorization: Bearer $PYAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[{"kb_id": "kb_...", "weight": 1}]'
```

**Or org-wide defaults** (every Omni session without an agent-specific binding
grounds against these):

```bash theme={null}
curl -X PUT https://api.pyai.com/v1/knowledgebases/default \
  -H "Authorization: Bearer $PYAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[{"kb_id": "kb_...", "weight": 1}]'
```

`weight` tunes retrieval priority when several bases are bound. The binding
route needs `omni:session` (it rides the agent profile surface); everything
under `/v1/knowledgebases` needs `kb:manage`.

## Step 4, talk

Nothing about the session changes. Open Omni as usual and the agent answers
from the bound bases:

```
wss://api.pyai.com/v1/omni?session_label=agent_...&format=pcm16&rate=24000
```

## FAQ

### Hosted knowledge base or my own kb\_endpoint?

Use a hosted knowledge base when you want PyAI to store, chunk, embed, and
retrieve your content with zero infrastructure. Use `kb_endpoint` when the
content already lives in your systems, changes too fast to sync, or needs
per-request logic (the `session_label` is echoed to your endpoint so you can
branch per caller).

### When is content visible to agents?

After the document reaches `indexed`. Ingestion is asynchronous; poll the
document or list documents and check `status`.

### What happens when I delete a knowledge base?

`DELETE /v1/knowledgebases/{id}` removes the base and its chunks. Agents bound
to it fall back to the org defaults (or to no grounding if none are set).

## Next steps

<CardGroup cols={2}>
  <Card title="Omni tools" href="/guides/omni-tools">Hosted, server, and client tools, including knowledge search.</Card>
  <Card title="Create agents via API" href="/guides/create-agents-api">Bind a hosted base to a stored profile.</Card>
  <Card title="API reference" href="/api-reference">Every `/v1/knowledgebases` endpoint, with schemas.</Card>
  <Card title="Quickstart" href="/quickstart">Mint a key and open your first Omni session.</Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.