> ## 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.

# Knowledgebases

## Worked knowledge-bases samples

The endpoint list below documents every operation's parameters; this
overlay walks a knowledge base the way an AI-agent integration actually
uses it: **list the knowledge bases → read their documents → upload one
document → handle a stale or rejected-upload error**. Success envelopes
are `{ data, meta }`, error envelopes `{ error, meta }` — see [How to
read a worked sample](/guides/using-orbit-samples). Run samples with a
sandbox (`dv_test_sk_*`) key; documents the pipeline cannot validate
(`error` indexing status) never enter the agent's retrieval set, and
you can re-queue them via the retry endpoint (see [Knowledge
bases](/knowledge/basics)).

Every response carries `meta.request_id` and `meta.timestamp`. Quote the
request id when you report a failing upload or a drifted document
status.

### 1. List knowledge bases

`GET /api/v1/knowledge-bases` returns your workspace's knowledge-base
records — id, name, description, optional config, refresh cadence — with
pagination. Use this to populate an AI-agent threading UI or pick the kb
to which a document will be uploaded.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.orbit.devotel.io/api/v1/knowledge-bases" \
    -H "X-API-Key: dv_test_sk_YOUR_KEY"
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/knowledge-bases",
    {
      headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
    },
  );
  console.log(await res.json());
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "knowledge_bases": [
      {
        "id": "kb_8fb2d1b7c00c4ec9",
        "name": "Checkout troubleshooting",
        "description": "Returns/ refund rules / payment errors",
        "refresh_schedule": "weekly",
        "document_count": 3
      }
    ],
    "pagination": { "cursor": null, "has_more": false }
  },
  "meta": {
    "request_id": "req_kb_list",
    "timestamp": "2026-08-26T12:00:00.000Z"
  }
}
```

Field notes a reader will hit on first integration:

* `refresh_schedule` is `manual` (default) or one of the recurring
  cadence values the create endpoint accepts — the non-`manual` values
  drive recurring re-scrape of URL/RSS/Notion sources.
* `document_count` is a read cache; update it with the list- read and use
  the `documents` endpoint below for per-file truth.

### 2. Read a knowledge base's documents

`GET /api/v1/knowledge-bases/{id}/documents` returns the document ledger for one knowledge base — the rows an operator sees on the dashboard — and reports pre-ingest status for each file (`pending`, `indexed`, `error`, `failed`). A rejected upload tells you the analysis and moderation pipeline flagged it so you can act on the offending chunk.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    "https://api.orbit.devotel.io/api/v1/knowledge-bases/kb_8fb2d1b7c00c4ec9/documents" \
    -H "X-API-Key: dv_test_sk_YOUR_KEY"
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/knowledge-bases/kb_8fb2d1b7c00c4ec9/documents",
    {
      headers: { "X-API-Key": process.env.ORBIT_API_KEY! },
    },
  );
  console.log(await res.json());
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "documents": [
      {
        "id": "doc_8fb2d1b7c00c4ec9",
        "name": "returns-policy.md",
        "type": "markdown",
        "status": "indexed",
        "version": 2,
        "created_at": "2026-08-01T12:00:00.000Z"
      }
    ]
  },
  "meta": {
    "request_id": "req_kb_documents",
    "timestamp": "2026-08-26T12:01:00.000Z"
  }
}
```

### 3. Upload one document

`POST /api/v1/knowledge-bases/{id}/documents` ingests a text/markdown document into the knowledge base. The body is the `uploadDocumentSchema` — `name`, `type` (one of the allowed text-code/image formats via vision
OCR), and `content` up to the router's 10 MB text-upload cap. Files larger than that need the multipart endpoint the dashboard uses; an image upload flows through OCR transcription and chains into the same retrieval set.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST \
    "https://api.orbit.devotel.io/api/v1/knowledge-bases/kb_8fb2d1b7c00c4ec9/documents" \
    -H "X-API-Key: dv_test_sk_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "name": "returns-policy.md",
    "type": "markdown",
    "content": "# Returns — 30-day window\n\n…"
  }'
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    "https://api.orbit.devotel.io/api/v1/knowledge-bases/kb_8fb2d1b7c00c4ec9/documents",
    {
      method: "POST",
      headers: {
        "X-API-Key": process.env.ORBIT_API_KEY!,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        name: "returns-policy.md",
        type: "markdown",
        content: "# Returns — 30-day window\n\n…",
      }),
    },
  );
  console.log(await res.json());
  ```
</CodeGroup>

```json 200 theme={null}
{
  "data": {
    "id": "doc_9e8d7c6b5a4f3021",
    "status": "pending",
    "version": 1
  },
  "meta": {
    "request_id": "req_kb_upload",
    "timestamp": "2026-08-26T12:02:00.000Z"
  }
}
```

### 4. Errors

Errors follow the `{ error, meta }` envelope. The failure every uploader
hits:

**422 — validation.** A name past 200 characters, unsupported `type`, or
a body over the text-upload cap:

```json 422 theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Document content too large (max 10MB). Split the file or upload via the multipart endpoint.",
    "status": 422
  },
  "meta": {
    "request_id": "req_kb_err",
    "timestamp": "2026-08-26T12:03:00.000Z"
  }
}
```
