Skip to main content

Knowledge

The library agents work from — versioned documents, playbooks, and RAG collections.

Overview

Upload files to a collection — PDFs, docs, spreadsheets, markdown — and the platform ingests them (text extraction, chunking, embedding), versions every update, and lets a collection be queried directly (:query) to preview retrieval before an Agent is bound to it. Collections are project-scoped, like every other resource (see Projects).

See the OpenAPI spec for the full endpoint and schema reference, or browse it rendered under API Reference → Knowledge.

Data Model

KnowledgeCollection

FieldTypeDescription
idstringPublic collection ID.
project_idstringThe owning project.
namestringHuman-readable label.
descriptionstring, nullable
document_countintegerNumber of documents currently in the collection.
created_atstring (date-time)
updated_atstring (date-time)

KnowledgeDocument

FieldTypeDescription
idstringPublic document ID.
collection_idstringThe collection it belongs to.
project_idstringThe owning project.
filenamestring, nullable
content_typestring, nullableMedia type of the source file; null for inline text.
statusstringpending, indexed or failed.
errorstring, nullableWhy ingestion failed; null otherwise.
sizeinteger, nullableSource size in bytes.
chunk_countinteger, nullableEmbedded chunks produced; null until ingestion finishes.
contentstring, nullableExtracted text — returned on get, null on list.
created_atstring (date-time)
updated_atstring (date-time)

KnowledgeConverter

FieldTypeDescription
idstringPublic converter ID.
project_idstringThe owning project.
content_typestringThe media-type glob it claims (image/*, audio/mpeg).
agent_idstring, nullableThe agent that converts the file.
tool_idstring, nullableThe tool that converts the file.
preset_parametersobject, nullableFixed arguments merged into every tool-converter call.
native_extractionstringfirst (convert only when native extraction finds no text) or skip (always convert).
chunk_strategystring, nullableDefault chunking for documents this converter produces.
chunk_sizeinteger, nullable
chunk_overlapinteger, nullable
created_atstring (date-time)
updated_atstring (date-time)

Key Concepts

Inline text or an uploaded file

A document is created from content (inline text) or from file — the bytes, base64-encoded, with a content_type and a filename. Exactly one of the two. application/pdf, text/plain and text/markdown are read directly; everything else needs a converter (below). Files are capped at 8 MiB of decoded bytes; over that the call is a 413 file_too_large.

Chunking

Ingestion splits the extracted text before embedding it, and chunk_strategy picks how:

StrategySplits intoUse it when
page (default)one chunk per pageYou want retrieved passages to cite a page number.
sizefixed-width character windows (chunk_size / chunk_overlap)Pages are dense and whole-page retrieval is too fuzzy. Windows are not page-aligned, so they carry no page number.
wholeone chunk for the documentThe document is already short — an OCR'd receipt, a single note.

Start with page, and move to size only if recall is poor on dense documents.

Converters

A converter makes a media type the platform cannot read natively — an image, an audio file — ingestable, by mapping a content_type glob onto an agent or a tool:

  • Agent converter (agent_id) — the file goes to a multimodal model with a fixed "extract all the text" instruction and its answer becomes the document text. Nothing to map; the shortest path for images and scanned PDFs.
  • Tool converter (tool_id) — the file is passed to an http tool as { content_type, filename, data_base64 } and whatever string the tool returns becomes the document text. The path for a dedicated non-chat API — a speech-to-text endpoint, a specialist OCR engine — which no LLM can call. Use the tool's execute.body_mode: "multipart" for form-data endpoints and its output_mapping to reduce a JSON response to the bare string.

Ingestion never names a converter: POST /v1/projects/{project_id}/knowledge/collections/{collection_id}/documents resolves the matching one from the file's content_type every time. A media type with no converter is a 400 unsupported_content_type and no document is created.

A converter matching a natively-readable type (application/pdf) is consulted only when native extraction yields no text — which is exactly what makes it a scanned-PDF fallback, leaving born-digital PDFs on the fast path. Set native_extraction: "skip" to OCR every PDF regardless.

Ingestion status

Documents are ingested asynchronously; a failed or unsupported file is an explicit failure state rather than a silent drop. status moves from pending to indexed or failed, and the transition is announced by the knowledge.document_ingested / knowledge.ingest_failed webhook events. A failed document carries the reason in error; POST /v1/projects/{project_id}/knowledge/collections/{collection_id}/documents/{document_id}:reingest retries it.

Retrieval preview

POST /v1/projects/{project_id}/knowledge/collections/{collection_id}:query answers "which chunks would an agent retrieve for this question?" without requiring an agent to be bound to the collection first.

Examples

naturali create-knowledge-collection \
--project-id proj_V1StGXR8Z5jdHi6B \
--name product-docs

Add a PDF to it — the bytes base64-encoded, with the media type that drives routing:

naturali create-knowledge-document \
--project-id proj_V1StGXR8Z5jdHi6B \
--collection-id kcol_V1StGXR8Z5jdHi6B \
--filename printer-x1000.pdf \
--content-type application/pdf \
--file "$(base64 -w0 printer-x1000.pdf)"

Register a converter so images become ingestable too:

naturali create-knowledge-converter \
--project-id proj_V1StGXR8Z5jdHi6B \
--content-type 'image/*' \
--agent-id agent_V1StGXR8Z5jdHi6B \
--chunk-strategy whole

For the walkthroughs, see Search a library of PDFs, Ingest images and audio, and Split a library between agents for organizing a knowledge base into topic collections, each with its own agent.