API reference

A small REST API over your documents. Load files or archives, then ask questions and get answers grounded in what you loaded, with citations. Base URL https://trove.techmaven.us.

Authentication

Every /v1 endpoint takes a bearer token. Browser sessions on /app use a signed cookie instead, so the same endpoints work from the UI without a token.

header
Authorization: Bearer $TROVE_KEY
Keys are supplied per deployment through the TROVE_API_KEYS environment variable (comma-separated). Documents are scoped to the key that uploaded them β€” one key cannot read another key's records.

Errors

Errors return the appropriate status with a JSON body of {"detail": "..."}.

StatusMeaning
400Malformed request, or no documents loaded yet
401Missing or invalid credentials
404No such document or job
415Unsupported file type
422File recognised but could not be parsed
502The configured inference endpoint is unreachable or errored

Upload a file

POST/v1/documents

Multipart upload of a single file. The document is parsed to text on ingest; structured formats keep their structure. Supported: pdf, docx, xml, ccda, csv, json, txt, md, html, log. Limit 40 MB per file.

request
curl -X POST https://trove.techmaven.us/v1/documents \
  -H "Authorization: Bearer $TROVE_KEY" \
  -F "file=@patient-record.xml"
200
{
  "id": "d_9f2c41ab7e30",
  "filename": "patient-record.xml",
  "pages": 1,
  "chars": 2841,
  "bytes": 291744,
  "created": 1754444102.7
}
Note the ratio. A 291 KB clinical document reduces to 2.8 KB of clinically meaningful text. Structural pre-filtering on ingest is what keeps large corpora small enough to read in full rather than retrieve over.

Ingest from a URL

POST/v1/ingest-url

Downloads a file or archive and ingests every member. ZIP and TAR are expanded automatically; anything else is treated as a single document. Returns immediately with a job id β€” poll job status for progress.

request
curl -X POST https://trove.techmaven.us/v1/ingest-url \
  -H "Authorization: Bearer $TROVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/records.zip","max_files":5000}'
202
{ "job_id": "job_4c81de90f2a7",
  "status": "queued",
  "source": "https://example.com/records.zip" }

Limits: 500 MB per download, 5,000 files per archive. Directory entries, dotfiles and path-traversal entries are skipped.

Job status

GET/v1/jobs/{job_id}

Status moves queued β†’ downloading β†’ processing β†’ complete, or failed with a message.

200
{
  "id": "job_4c81de90f2a7",
  "status": "processing",
  "total": 1180,
  "processed": 725,
  "failed": 0,
  "message": null
}

List documents

GET/v1/documents
200
{ "data": [ { "id": "d_9f2c41ab7e30",
             "filename": "patient-record.xml",
             "pages": 1, "chars": 2841,
             "bytes": 291744,
             "created": 1754444102.7 } ],
  "total": 1 }

Delete a document

DELETE/v1/documents/{id}
200
{ "deleted": "d_9f2c41ab7e30" }

Ask a question

POST/v1/ask

Answers from the documents you have loaded. Omit document_ids to ask across everything.

FieldTypeDescription
questionstringRequired. Up to 8,000 characters.
document_idsstring[]Optional. Restrict to specific documents.
streambooleanOptional. Server-sent events instead of one response.
request
curl -X POST https://trove.techmaven.us/v1/ask \
  -H "Authorization: Bearer $TROVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question":"Find all patients with a documented history of cancer"}'
200
{
  "answer": "102 patients have a documented history of cancer…",
  "citations": [ { "tag": "d1",
                    "document_id": "d_9f2c41ab7e30",
                    "filename": "Alejandra902_Villa94.xml" } ],
  "model": "glm-5.2",
  "documents_searched": 1180,
  "elapsed_ms": 18402
}

The [d1] markers inside answer correspond to tag values in citations, so each claim can be traced to its source document.

Streaming

Set "stream": true to receive server-sent events. The first event carries the citation set, then tokens arrive as they are generated.

text/event-stream
data: {"type":"start","citations":[…],"model":"glm-5.2"}
data: {"type":"token","text":"102 patients"}
data: {"type":"token","text":" have a documented"}
data: {"type":"done"}

Health

GET/v1/health

Unauthenticated. Reports whether the configured inference endpoint is reachable.

200
{ "status": "ok",
  "model": "glm-5.2",
  "inference_ok": true,
  "documents": 1180 }

Self-hosting

Trove reaches the model through one OpenAI-compatible base URL. Serve the weights on your own hardware and no document leaves your network. Nothing else in the configuration changes.

environment
# the only integration point
TROVE_LLM_BASE_URL=http://localhost:8000/v1
TROVE_LLM_MODEL=zai-org/GLM-5.2
TROVE_LLM_API_KEY=EMPTY          # unauthenticated local servers ignore this

# access control
TROVE_API_KEYS=key_one,key_two
TROVE_APP_PASSWORD=…            # browser access to /app

# limits
TROVE_CONTEXT_CHARS=600000       # read-everything budget before ranking kicks in
TROVE_MAX_DOWNLOAD=524288000
TROVE_DATA_DIR=/var/lib/trove
ServerCommand
vLLMvllm serve zai-org/GLM-5.2 --port 8000 --tensor-parallel-size 8
SGLangpython -m sglang.launch_server --model-path zai-org/GLM-5.2 --port 8000
Ollamaollama serve  β†’  http://localhost:11434/v1
TGItext-generation-launcher --model-id Qwen/Qwen3-32B --port 8000