Ingestion

Routing, files, deduplication and what happens after content arrives.

Four ways in: connectors, file uploads, the ingest endpoint, and space conversation capture. All four converge on the same pipeline.

The pipeline

Everything after the perimeter scan happens in the background. The write returns as soon as the content is safely accepted.

Text and structured content

POST/api/v1/memory/ingest

Accepts text, markdown, html, json and code.

{
  "content": "# Acme Q4 review\n\nDeal moved to Security Review.",
  "content_type": "markdown",
  "routing": { "mode": "auto" },
  "metadata": { "source_system": "crm", "author": "jana@acme.com" }
}

Send metadata liberally. It costs nothing at write time and gives you filtering you will want later.

Routing

ModeBehaviour
autoClassifier picks the department
manualYou supply vault_id
hybridYou pick the department, the classifier picks below it

Auto-routing declines to guess below 0.70 confidence and files the content in v_unassigned with needs_review: true.

Watch needs_review. Content in v_unassigned is still searchable memory-wide, but it is invisible to any department-scoped query — and nobody goes looking in a drawer marked "unassigned".

Pin what you already know:

{
  "content": "...",
  "routing": { "mode": "manual", "vault_id": "v_finance" }
}

Files

POST/api/v1/memory/uploads

PDF, DOCX, XLSX, CSV, TXT, Markdown and images. Scanned PDFs and images go through OCR automatically.

curl https://api.uni-flow.ai/api/v1/memory/uploads \
  -H "x-api-key: $CHORDIAN_API_KEY" \
  -F "file=@q4-report.pdf"

Optional query parameters space_id and vault_id tag and pin the file.

Returns status: "pending". Poll the upload or subscribe to memory.ingest.completed rather than sleeping and hoping.

Don't pre-chunk

Send whole documents. Chunking happens server-side with the full document in context; splitting into sentences beforehand throws away the context that would have produced better chunks.

Deduplication

Re-ingesting an unchanged document short-circuits rather than creating a duplicate, so a connector re-sync is cheap and safe to run.

To deliberately replace a document, pass options.overwrite_id.

The perimeter

Every path runs the data perimeter before storage. The response reports what was masked:

{ "doc_id": "ing_9f2c8a1e", "dlp_matches": 2 }

If the scanner cannot run, ingestion returns 503 with CHORD_DLP_UNAVAILABLE and nothing is stored. Retry with backoff — this is fail-closed by design.

Re-indexing

POST/api/v1/memory/uploads/{upload_id}/reindex

Re-runs extraction and indexing. Use it after changing perimeter rules or department structure — existing content is not retroactively re-processed otherwise.

Was this page helpful?
Report an issue

On this page