AI Knowledge & Logic

Knowledge Documents

Upload, inspect, archive and restore knowledge documents through MCP or REST, including safe automated refreshes.

Knowledge documents are files the bot can search for factual answers. They use the same ingestion, chunking and embedding pipeline whether uploaded from the dashboard, MCP or REST. Supported formats are TXT, CSV, Markdown, PDF, DOCX, XLSX and XLS. Real files must be non-empty and at most 25 MiB; CSV imports support up to 1,000 rows and spreadsheet imports up to 10,000 rows.

MCP tools

Use list_documents to find current documents with file IDs and indexing status; pass includeArchived: true to include retained archives. upload_document accepts inline text for TXT, CSV and Markdown. For a real file, call create_document_upload_url, PUT the original bytes to its temporary URL, then call finalize_document_upload with the returned fileId.

archive_document disables the document's context while retaining its file and embedding chunks. Find archived documents with list_archived_configuration_resources using resourceType: "document", and recover them with restore_document.

REST operations

All paths below start with /rest/v1 and require X-API-Key. Use the REST reference for complete request and response schemas. Copilot and MCP can discover these endpoints in the Documents group with list_rest_api_operations.

MethodPathPurpose
GET/documents?businessSlug=shopList active documents; add includeArchived=true to include retained archives
GET/documents/{id}?businessSlug=shopRead one document, its download URL and indexing status, including archives
POST/documentsUpload inline {businessSlug, filename, content} for TXT, CSV or Markdown, up to 500,000 characters
POST/documents/uploadsReserve a direct upload with {businessSlug, filename}
POST/documents/uploads/{fileId}/finalizeValidate and ingest uploaded bytes; body is {businessSlug}
DELETE/documents/{id}?businessSlug=shopRecoverably archive the exact document
POST/documents/{id}/restoreRestore the retained document and its previous context enablement; body is {businessSlug}

Documents are scoped to the API key's organization and requested business. Cross-business files cannot be finalized or used to archive another business's knowledge. Archived businesses remain readable but reject mutations. Python recurring jobs can use their injected OCTOCOM_ORG_API_KEY and OCTOCOM_API_BASE_URL with the same endpoints.

Upload reservations return {data: {fileId, presignedUrl, uploadHeaders}}. PUT the original bytes, without an Octocom API key, to presignedUrl using the exact uploadHeaders, including x-ms-blob-type: BlockBlob. Do not encode a PDF, Word document or spreadsheet as inline text. Finalization checks size, format and file safety before ingestion. Repeated finalization of the same fileId returns its existing document, even if it was archived; it does not create a second document or restore it.

Upload and download URLs are credentials. Keep them out of logs and version control. Private download links expire at urlExpiresAt; request document details again when you need a fresh one. Responses containing these links use Cache-Control: no-store.

Safely refresh a document

Uploading the same filename creates a new document. There is no implicit overwrite or deletion. Keep the old document active until the new one is ready:

  1. Fetch and validate the complete new source content. Save the old document ID.
  2. Upload the replacement and save its returned document ID. Binary uploads require the direct-byte upload and finalization steps above.
  3. Poll the replacement with GET until data.status is ready.
  4. Archive the saved old document ID. Do not select it by filename alone.

Ingestion parses the file before returning, but indexing continues asynchronously. Document status has four possible values:

StatusMeaning
indexingExtracted content is not fully chunked and embedded yet
readyAll extracted context elements are indexed and embedding chunks exist
emptyThe file produced no searchable context; keep the old document
archivedThe document is retained but its archived context is disabled

indexing includes work that has not completed, including failed background indexing. Use a bounded polling deadline and inspect failures if it does not become ready. A timeout or ingestion error is not a reason to archive the old snapshot. Record IDs in durable organization storage so a later run can resume or inspect an uncertain upload, rather than creating another replacement.

For example, after uploading a replacement through REST:

import requests
import time

def wait_for_document(business_slug, document_id, timeout=40):
    url = f"{OCTOCOM_API_BASE_URL}/rest/v1/documents/{document_id}"
    deadline = time.monotonic() + timeout
    while time.monotonic() < deadline:
        response = requests.get(
            url,
            params={"businessSlug": business_slug},
            headers={"X-API-Key": OCTOCOM_ORG_API_KEY},
            timeout=10,
        )
        response.raise_for_status()
        document = response.json()["data"]
        if document["status"] == "ready":
            return document
        if document["status"] in {"empty", "archived"}:
            raise RuntimeError("Replacement is not searchable; keep the old document")
        time.sleep(1)
    raise TimeoutError("Replacement is not ready; keep the old document")

Archival and restoration are idempotent. Archival preserves the original enablement of each context element, and restoration reuses the retained chunks without another download or embedding request. Document writes are included in configuration history; API request audit also retains execution-token identity for Python-triggered requests. File contents and signed URLs are not copied into document change snapshots.

On this page