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

# Knowledge bases

## Worked sequences

The twenty operations below are the full knowledge-base surface, but four
round trips cover the document lifecycle most integrations actually run:
upload a document, moderate it once the review queue picks it up, search
the base to preview what an agent would retrieve, and diff two versions
when the ground truth changed. Each sequence shows the body you send and
the body the API returns. For the prose walkthrough of the whole lifecycle
(create → load → attach → tune → maintain), read
[Build and Maintain an AI Knowledge Base](/guides/knowledge-base-lifecycle).

You need the `knowledge:write` scope (owner / admin / developer role) for
uploads and moderation, and `knowledge:read` for search and diffs.

### 1. Upload a document

Binary files (PDF, DOCX, images — OCR-extracted) go up as
`multipart/form-data`. Send the file bytes plus the `name` and `type`
fields; the accepted document comes back in `processing` status because
chunking and embedding run asynchronously. Poll
`GET /knowledge-bases/kb_abc123/documents` until the status reaches
`ready`.

```bash theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/knowledge-bases/kb_abc123/documents" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -F "file=@refund-policy.pdf" \
  -F "name=Refund Policy" \
  -F "type=pdf"
```

```typescript Node.js theme={null}
import { readFileSync } from "node:fs";

const form = new FormData();
form.append("file", new Blob([readFileSync("refund-policy.pdf")]), "refund-policy.pdf");
form.append("name", "Refund Policy");
form.append("type", "pdf");

const res = await fetch(
  "https://api.orbit.devotel.io/api/v1/knowledge-bases/kb_abc123/documents",
  {
    method: "POST",
    headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
    body: form,
  },
);
console.log(await res.json());
```

```json 202 theme={null}
{
  "data": {
    "id": "doc_9a1c3e5b7d",
    "knowledge_base_id": "kb_abc123",
    "name": "Refund Policy",
    "type": "pdf",
    "status": "processing",
    "version": 1
  },
  "meta": {
    "request_id": "req_01H2T4W6YF8E9K3Z0VX5QAB7CJ",
    "timestamp": "2026-08-22T11:41:00.000Z"
  }
}
```

A `422` on a multipart upload means a missing `name`/`type` field or raw
JSON carrying binary bytes — binary formats are multipart-only (inline
text under the 10 MB cap may go up as a JSON `content` body instead; see
the operation below).

### 2. Approve or reject a pending document

A document submitted for moderation (for example, a gap-cluster draft)
sits pending until a reviewer acts. Approving flips its publish lifecycle
to `approved` and starts deferred vector indexing so its chunks become
retrievable; rejecting flips it to `rejected` and its chunks are never
indexed. Optional `notes` are stored on the document for the submitter.

Approve:

```bash theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/knowledge-bases/kb_abc123/documents/doc_9a1c3e5b7d/approve" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "notes": "Reviewed against the 2026-08 returns update." }'
```

```json 200 theme={null}
{
  "data": {
    "id": "doc_9a1c3e5b7d",
    "knowledge_base_id": "kb_abc123",
    "name": "Refund Policy",
    "status": "approved",
    "notes": "Reviewed against the 2026-08 returns update."
  },
  "meta": {
    "request_id": "req_01H2T4X1PF3E9K0ZVX6QCB8DK",
    "timestamp": "2026-08-22T12:10:00.000Z"
  }
}
```

Reject:

```bash theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/knowledge-bases/kb_abc123/documents/doc_9a1c3e5b7d/reject" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "notes": "Superseded by the 2026-08 policy revision." }'
```

```json 200 theme={null}
{
  "data": {
    "id": "doc_9a1c3e5b7d",
    "knowledge_base_id": "kb_abc123",
    "name": "Refund Policy",
    "status": "rejected",
    "notes": "Superseded by the 2026-08 policy revision."
  },
  "meta": {
    "request_id": "req_01H2T4X4RG4F9L1ZVY7RDC9EM",
    "timestamp": "2026-08-22T12:12:00.000Z"
  }
}
```

Both actions are audit-logged — approval promotes a document to RAG
ground-truth, which is an admin-class decision.

### 3. Search the knowledge base

This is the same retrieval an attached agent's `search_knowledge` tool
runs, and the response shape exists so you can preview what an agent would
ground on before a customer asks. Results are relevance-ranked chunks;
when a per-base search config is active, recency, source weighting, and
category filters apply before the list is truncated to `limit` (default
5\).

```bash theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/knowledge-bases/kb_abc123/search" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "How long do annual-plan refunds take?",
    "limit": 3
  }'
```

```json 200 theme={null}
{
  "data": {
    "query": "How long do annual-plan refunds take?",
    "knowledge_base_id": "kb_abc123",
    "results": [
      {
        "content": "Annual-plan refunds are processed within 5–7 business days of approval.",
        "score": 0.87,
        "documentId": "doc_9a1c3e5b7d",
        "document_name": "Refund Policy",
        "knowledge_base_id": "kb_abc123",
        "chunkIndex": 2
      },
      {
        "content": "Pro-rated refunds apply to annual subscriptions cancelled mid-term.",
        "score": 0.81,
        "documentId": "doc_9a1c3e5b7d",
        "document_name": "Refund Policy",
        "knowledge_base_id": "kb_abc123",
        "chunkIndex": 4
      }
    ]
  },
  "meta": {
    "request_id": "req_01H2T4Y2QH5G0M2ZWZ8SED1FN",
    "timestamp": "2026-08-22T12:20:00.000Z"
  }
}
```

An empty `results` array means no chunk cleared the raw similarity floor —
check whether the document you expect is uploaded, approved, and indexed.

### 4. Diff two document versions

Every re-upload retains the prior copy as an immutable snapshot, so you
can always ask what changed. `GET
/knowledge-bases/kb_abc123/documents/doc_9a1c3e5b7d/versions/diff` takes
`from` and `to` 1-based version numbers and returns added / removed /
unchanged line counts plus unified-style hunk lines (`+` added, `-`
removed, ` ` context). `truncated: true` means the inputs were too large
for a line-level diff. A `422` here means one of those versions isn't in
the retained lineage.

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/knowledge-bases/kb_abc123/documents/doc_9a1c3e5b7d/versions/diff?from=1&to=2" \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

```json 200 theme={null}
{
  "data": {
    "knowledge_base_id": "kb_abc123",
    "document_id": "doc_9a1c3e5b7d",
    "from_version": 1,
    "to_version": 2,
    "added": 4,
    "removed": 2,
    "unchanged": 61,
    "truncated": false,
    "hunks": [
      "- Refunds take up to 10 business days.",
      "+ Annual-plan refunds are processed within 5–7 business days of approval.",
      "+ Enterprise contracts follow the contractual SLA instead."
    ]
  },
  "meta": {
    "request_id": "req_01H2T4Y6RJ6H1N3ZX0ATFE2GQ",
    "timestamp": "2026-08-22T12:26:00.000Z"
  }
}
```

To restore an earlier version, `POST
/knowledge-bases/kb_abc123/documents/doc_9a1c3e5b7d/rollback` with
`{ "version": 1 }` — non-destructive, since the current head is
snapshotted first.
