Naxis Technologies Docs
Live demo

The built-in API cards

Ingestion API — push documents in

The Ingestion API lets your own application push documents into the knowledge base over HTTP, instead of a connector pulling them. It's a source like any other — what it ingests is indexed, access-controlled, analysed and retained exactly the same way. This article is the complete reference.

Setup

  1. Documents → Ingestion API/MCP: name it, and choose which groups may read what it ingests (that becomes each document's default access).
  2. Open the source and copy its endpoint and key from “API endpoint & key”. Rotate issues a new key and invalidates the old at once.

Authentication

Send the key in an Authorization: Bearer header on every request. The key belongs to this one source — it can ingest, never message. A missing or wrong key returns 401.

Endpoints

Document fields

external_idYour stable id for the document (1–512 chars: letters, digits, . _ : / -, starting alphanumeric). Send the same id again to update the document in place.
titleOptional display title.
textInline content — markdown, HTML or plain text. Provide exactly one of text or content_base64.
content_base64Base64-encoded bytes for binary formats (PDF, DOCX…). 50 MB per document, 100 MB per request.
filename / content_typeOptional hints for format detection; derived from external_id and content when omitted.
aclOptional list of groups (e.g. ["grp:support"]). Named groups must already exist — an unrecognised name is rejected rather than silently dropped. Omit it to use the source's own groups.
metadataOptional free-form JSON stored with the document.

Example

A single request that creates or replaces one document, in curl:

curl -X POST <base>/api/v1/ingest/documents \
  -H "Authorization: Bearer <key>" \
  -H "Content-Type: application/json" \
  -d '{"external_id":"kb/refunds",
       "title":"Refund policy",
       "text":"# Refunds\nWe refund within 30 days.",
       "acl":["grp:support"]}'

The same call in Python, checking the response and reading the error body when it fails:

import requests

resp = requests.post(
    "<base>/api/v1/ingest/documents",
    headers={"Authorization": "Bearer <key>"},
    json={
        "external_id": "kb/refunds",
        "title": "Refund policy",
        "text": "# Refunds\nWe refund within 30 days.",
        "acl": ["grp:support"],
    },
)

if resp.status_code == 202:
    body = resp.json()
    print("queued, job", body["job"], "->", body["uri"])
else:
    # error bodies are {"detail": "..."}
    print(resp.status_code, resp.json().get("detail"))

And in JavaScript, using fetch on Node 18 or later:

const resp = await fetch("<base>/api/v1/ingest/documents", {
  method: "POST",
  headers: {
    "Authorization": "Bearer <key>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    external_id: "kb/refunds",
    title: "Refund policy",
    text: "# Refunds\nWe refund within 30 days.",
    acl: ["grp:support"],
  }),
});

const body = await resp.json();
if (resp.status === 202) {
  console.log("queued, job", body.job, "->", body.uri);
} else {
  // error bodies are { detail: "..." }
  console.error(resp.status, body.detail);
}

Behaviour worth knowing

Machine-readable spec for Postman/codegen: /api/v1/openapi.json.

Was this page helpful?
Was this page helpful? Sign in with Google Sign in to tell us — or leave a comment.

Last updated 20 Sep 2026