atrium

HTTP API

Every route, what it takes and what it returns.

Ten routes. Six of them do the work; the rest are a sandbox and a visualiser.

MethodPathStatusWhat it does
POST/ingest200Ingest files inline — parsed, embedded and stored before the response
POST/jobs202Queue a file for the worker; returns a job_id immediately
GET/jobs/{job_id}200Job status: pending, running, complete, failed
POST/search200Search the corpus
POST/preview200Parse and chunk without embedding or storing
GET/health200 / 503Liveness, plus whether the vector store and the embedder answer
GET/visualize200A page for looking at the chunks
GET/retrieval_lab200A sandbox: chunk, embed and score one document in RAM
POST/retrieval_lab/prepare200Load a document into the sandbox
POST/retrieval_lab/search200Query the sandbox

POST /ingest

Ingest one or more files. The response comes back after the documents are parsed, embedded and stored.

Form fields

FieldRequiredWhat it is
filesyesThe file. Repeat for more than one.
doc_idsnoComma-separated document ids, aligned with the files. Defaults to a generated uuid.
chunking_modenoauto (default), balanced, precise, context_rich, custom.
chunking_confignoA JSON object of chunking overrides. Only used with chunking_mode=custom.
curl -X POST http://localhost:8000/ingest \
    -F "files=@./report.pdf" \
    -F "files=@./notes.docx" \
    -F "doc_ids=report,notes"
{
  "jobs": [
    {"job_id": "…", "doc_id": "report", "filename": "report.pdf"},
    {"job_id": "…", "doc_id": "notes", "filename": "notes.docx"}
  ]
}

A file that fails to parse comes back with an error field on its job rather than a silent success.

POST /jobs

Queue a file for asynchronous ingestion. The response is immediate; a worker claims the job and does the work.

curl -X POST http://localhost:8000/jobs -F "file=@./big-report.pdf"
{"job_id": "…", "doc_id": "…", "filename": "big-report.pdf"}

The document is held in the job queue until a worker claims it, so it gets a tighter cap than the inline path: 50 MB. A larger body is rejected with 413. A file whose declared content type contradicts its bytes — a PDF that is really HTML — is rejected with 415.

The worker is a separate process:

python -m atrium.worker

GET /jobs/{job_id}

{"status": "complete", "chunks_written": 82, "error": null}

status is one of pending, running, complete, failed. A failed job carries the reason in error.

POST /search

Search the corpus.

Body

FieldTypeDefaultWhat it is
querystringrequiredThe question.
top_kintegerDEFAULT_TOP_K (8)How many results. 1–100.
rerankboolean | nullfollows RERANK_ENABLEDTri-state: true forces the cross-encoder on, false forces it off.
candidate_kintegerthe adapter's defaultHow many candidates to fetch before reranking.
score_thresholdnumbernoneDrop results below this cosine similarity.
curl -X POST http://localhost:8000/search \
    -H 'Content-Type: application/json' \
    -d '{"query": "retention policy", "top_k": 8, "rerank": false}'
{
  "query": "retention policy",
  "top_k": 8,
  "rerank": false,
  "count": 8,
  "took_ms": 41,
  "results": [
    {
      "rank": 1,
      "score": 0.781,
      "chunk_id": "b0083c00-…",
      "doc_id": "policy",
      "text": "Records are retained for 24 months…",
      "page_number": 14,
      "section_path": ["Retention", "Data lifecycle"],
      "element_type": "paragraph",
      "chunking_strategy": "structure_aware",
      "is_parent": false,
      "parent_id": null,
      "parent_text": null,
      "parent_page_number": null,
      "parent_section_path": []
    }
  ]
}

The result fields

FieldWhat it is
rankPosition in the result list, from 1.
scoreCosine similarity against the query.
chunk_idThe chunk's id. Stable for a given chunking strategy.
doc_idThe document id you supplied, or a generated uuid.
textThe chunk's text.
page_numberThe page the chunk starts on.
section_pathThe heading path above the chunk.
element_typeheading, paragraph, list_item, table, code, image_caption or footnote.
chunking_strategyThe strategy that produced this chunk.
is_parentWhether this chunk is a parent (context) chunk.
parent_idThe parent chunk's id, if any.
parent_textThe parent chunk's text, if any.
parent_page_numberThe parent chunk's page.
parent_section_pathThe parent chunk's heading path.

page_number and section_path are the reason to use Atrium rather than a chunker: they are what makes a retrieved passage citable.

POST /preview

Parse and chunk a document without embedding or storing it. Same form fields as /ingest.

curl -X POST http://localhost:8000/preview \
    -F "file=@./report.pdf" \
    -F "chunking_mode=precise"

GET /health

{"status": "ok", "db": true, "embedder": true, "vector_db_type": "qdrant"}

200 when the service is up and the dependencies answer, 503 when it is degraded. The container health check treats any response as "the process is alive" — a 503 means the vector store is down, not that the API needs restarting.

The retrieval lab

/retrieval_lab is a sandbox: it chunks, embeds and scores a single uploaded document against an in-RAM cosine matrix. No vector store, no sparse ranker, no reranker. It is for looking at one document; use /search to query what you have actually ingested.

Authentication

With API_KEY set, every route except /health and /visualize requires a bearer token:

curl -H "Authorization: Bearer $API_KEY" -X POST http://localhost:8000/search -d '{"query":"…"}'

The schema browsers (/docs, /redoc, /openapi.json) are open.

Atrium Cloud

Don't want to run it yourself? Atrium Cloud is coming.

It is not here yet — the list is what there is until it is. The library is free, MIT licensed, and yours either way.

On this page