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

# Documents overview

> Manage knowledge base documents — text, files, and URLs.

A knowledge base document holds the content an agent retrieves from
during a conversation. Documents come in three flavors:

* **Text** — raw text you provide directly. Best for brand voice,
  short reference docs, or pasted content.
* **File** — uploaded files (PDF, DOCX, EPUB, TXT, MD, HTML). The
  server extracts text, chunks it, and embeds the chunks for vector
  similarity retrieval.
* **URL** — a public web page or document. The server fetches it,
  extracts text, and ingests it the same way as a file.

Every document carries:

* A stable `id` like `kndoc_<cuid2>` (we diverge from ElevenLabs's
  bare-UUID convention to keep IDs prefixed and self-describing).
* A `name` (display title, defaults to the first line of text / the
  uploaded filename / the page `<title>`).
* A `folder_path` describing where the doc lives in your knowledge
  base's folder tree (root-first ancestor chain by ID + name).
* `metadata.size_bytes` (the doc's raw text size in bytes), plus
  ISO-8601 `created_at` and `updated_at` timestamps.
* A `type` of `text`, `file`, or `url`.
* A `status` of `pending`, `processing`, `ready`, or `failed`. A document
  only becomes retrievable via [search](#searching) and `/chunks` once
  it reaches `ready`. Documents created through the API today stay
  `pending` until a follow-up wires up server-side chunk + embed
  indexing (the existing path that runs from the Knowledge Base UI is
  not yet shared with the API).

## Creating documents

Three POST endpoints:

* `POST /v1/knowledge-base/documents/from-text` — JSON body with `text`,
  optional `name` and `folder_id`.
* `POST /v1/knowledge-base/documents/from-file` — multipart form with a
  `file` field (max 25 MB), plus optional `name` and `folder_id`.
  **Currently returns 501 Not Implemented.** The route shape is stable
  but the server-side file-ingestion pipeline (PDF/DOCX/EPUB/TXT
  extraction + blob storage + chunking) ships in a follow-up. Use the
  Knowledge Base UI to upload files in the meantime.
* `POST /v1/knowledge-base/documents/from-url` — JSON body with `url`
  (http(s) only), optional `name` and `folder_id`. The server fetches
  the URL, validates safety (SSRF guard, size cap, content-type
  allow-list), and extracts text.

All three return the full document object.

## Reading documents

* `GET /v1/knowledge-base/documents` — paginated list with optional
  filters (`folder_id`, `ids` for batch-get, `types`, `search`). Cursor
  pagination via the opaque `cursor` query param.
* `GET /v1/knowledge-base/documents/:id` — full document object.
* `GET /v1/knowledge-base/documents/:id/content` — raw text as
  `text/plain`.
* `GET /v1/knowledge-base/documents/:id/chunks` — paginated chunks of
  the doc after splitting + embedding.
* `GET /v1/knowledge-base/documents/:id/chunks/:chunkId` — one chunk by ID.
* `GET /v1/knowledge-base/documents/:id/source-file-url` — pre-signed
  URL (or redirect) to the doc's blob storage entry.
* `GET /v1/knowledge-base/documents/:id/agents` — agents that depend
  on this document.

## Updating documents

* `PATCH /v1/knowledge-base/documents/:id` — rename and/or move to a
  different folder. Body: `{ name?, folder_id? }`. Pass `folder_id: null`
  to move to root.
* `PATCH /v1/knowledge-base/documents/:id/file` — replace the source file
  for a file-typed document. Re-chunks and re-embeds transactionally.
  Returns 400 for non-file-typed docs. **Currently returns 501 Not
  Implemented** alongside `POST /from-file` (same follow-up).
* `POST /v1/knowledge-base/documents/:id/refresh` — re-fetches the source
  URL for a URL-typed document, re-extracts text, replaces chunks.
  Returns 400 for non-URL-typed docs.

## Deleting documents

* `DELETE /v1/knowledge-base/documents/:id` — hard delete. Chunks are
  cascade-deleted via the database constraint; any agent attachments
  through this document are also cleaned up.

## Searching

* `GET /v1/knowledge-base/search` — vector similarity search over the
  org's indexed chunks. Returns documents sorted by relevance with
  a `score` (0-1, higher is better) and a `search_snippet` (the
  matched chunk content, trimmed to 300 chars). Filters: `types`.

## Stats

* `GET /v1/knowledge-base/size` — `{ size_bytes, document_count, chunk_count }`
  for the org's knowledge base.

## Differences from ElevenLabs

Three documented divergences, surfaced explicitly:

1. **ID format** — `kndoc_<cuid2>` instead of bare UUID. Our convention
   prefixes every entity ID with a short type marker for log
   readability and forwards-compat with multi-tenant routing.
2. **Timestamps** — ISO-8601 strings (`"2026-05-21T11:00:00.000Z"`)
   instead of `*_unix_secs` integers. Easier to read; standard for
   modern API consumers.
3. **`access_info` omitted** — ElevenLabs returns a per-document
   `access_info` object. We don't have per-document ACLs — organisations
   are the access boundary — so we omit the field rather than return
   a misleading stub.

And one diverged endpoint:

* **`GET /v1/knowledge-base/size`** returns `{ size_bytes, document_count,
  chunk_count }`. ElevenLabs's equivalent returns `{ number_of_pages }`
  (a tokens/pages metric specific to their billing model). We expose
  the underlying real units.
