API — Documents & RAG
All routes 404 when {agent_id} doesn't resolve. The two query routes additionally require the document_search tool (403 otherwise).
POST /agents/{id}/documents/upload — ingest a document
Body: multipart/form-data with a single file field. Constraints: filename ends .txt, content decodes as UTF-8, text non-empty.
curl -X POST http://localhost:8001/agents/1/documents/upload -F "file=@sla.txt"{
"id": 1, "agent_id": 1, "filename": "sla.txt",
"file_type": "txt", "status": "indexed",
"chunks_count": 3, "created_at": "2026-07-16T10:30:00"
}400 with a specific message for wrong type / bad encoding / empty file. Pipeline internals (chunking 800/100, per-chunk embedding, dual store) and the partial-failure caveat: RAG Ingestion.
GET /agents/{id}/documents — list documents
200 → DocumentResponse[], newest first.
GET /agents/{id}/chunks — inspect stored chunks
200 → DocumentChunkResponse[], oldest first — full chunk_text, chunk_index, document_id. Useful for verifying chunk boundaries when retrieval misbehaves (quality levers).
POST /agents/{id}/documents/search — raw vector search
Body (DocumentSearchRequest): {"query": "string", "top_k": 3}
{
"query": "support SLA",
"results": [
{
"chunk_text": "Premium customers have a 4-hour support SLA...",
"score": 0.31,
"document_id": 1,
"filename": "sla.txt",
"chunk_index": 0
}
]
}Raw Chroma distance, not a similarity percentage. See Retrieval.
Side effect: document_search ToolCall. 500 on embedding/store failure (failed ToolCall committed first).
POST /agents/{id}/documents/ask — corrective-RAG answer
Body (RAGAnswerRequest): {"question": "string", "top_k": 3}
Runs the corrective RAG graph: retrieve → evaluate → answer or refuse.
{
"question": "What is the premium support SLA?",
"answer": "Premium customers have a 4-hour support SLA.",
"sources": [
{"filename": "sla.txt", "document_id": 1, "chunk_index": 0, "score": 0.31}
],
"retrieval_evaluation": {
"has_answer": true, "confidence": 0.95,
"reason": "The context states the premium SLA directly."
}
}{
"question": "What is our vacation policy?",
"answer": "I could not find this information in the uploaded documents.",
"sources": [ {"filename": "sla.txt", "...": "..."} ],
"retrieval_evaluation": { "has_answer": false, "confidence": 0.9, "reason": "..." }
}Interpretation: a refusal is a 200 with the fixed refusal string — check retrieval_evaluation.has_answer to distinguish programmatically. sources always lists what was retrieved, even on refusal (that's the debugging window).
Side effect: langgraph_corrective_rag ToolCall containing answer + sources + evaluation. 500 on any node failure.
Related pages
- RAG Overview — the subsystem
- Routers: Documents — implementation
- RAG Tutorial — hands-on