File Search API

Captain File Search retrieves source chunks from indexed files. Use v3 for new applications. It has cleaner response fields, explicit include controls, document inspection, chunk metadata, and graph relations.

v2 remains available for existing clients. It keeps search_results and content so older code does not break.

Query With v3

1import requests
2
3BASE_URL = "https://api.captain.dev"
4API_KEY = "your_api_key"
5COLLECTION = "medical_claims"
6
7response = requests.post(
8 f"{BASE_URL}/v3/collections/{COLLECTION}/query",
9 headers={
10 "Authorization": f"Bearer {API_KEY}",
11 "Content-Type": "application/json",
12 },
13 json={
14 "query": "What evidence supports the safety claim?",
15 "limit": 10,
16 "rerank": {
17 "enabled": True,
18 "candidate_limit": 30,
19 "model": "voyage-rerank-2.5",
20 },
21 "include": {
22 "document": True,
23 "metadata": True,
24 "regions": False,
25 "relations": True,
26 "related_chunks": True
27 }
28 },
29 timeout=120.0,
30)
31
32data = response.json()
33for result in data["results"]:
34 print(result["document"]["filename"], result["score"])
35 print(result["text"])

See the v3 Query endpoint for the full request and response schema.

Tuning reranking

rerank accepts a boolean or an object. true uses the defaults — voyage-rerank-2.5 over a candidate pool of limit × 3. The object form tunes it:

1{
2 "query": "payment authorization requirements",
3 "limit": 3,
4 "rerank": {
5 "enabled": true,
6 "candidate_limit": 50,
7 "model": "voyage-rerank-2.5"
8 }
9}
  • model — pick a reranker. Voyage cross-encoders: voyage-rerank-2.5 (default) and voyage-rerank-3 (aliases rerank-2.5, rerank-3). Gemini LLM rerankers: gemini-2.5-flash and gemini-3.8-flash — a higher quality ceiling on complex queries at higher latency, best with small candidate pools. The family aliases voyage and gemini resolve to each family’s default. Unknown values return a 400 listing the allowed set.
  • candidate_limit — how many fused retrieval candidates are fetched and reranked before the top limit results are returned. Defaults to limit × 3; must be ≥ limit, capped at 200. Raising it can lift recall on corpora with many near-duplicate documents, at the cost of rerank latency.
  • enabled — defaults to true in the object form; {"enabled": false} is an explicit opt-out, exactly like rerank: false.

The response’s rerank envelope reports what actually ran: used, reason, and — when reranking was applied — model and candidate_limit. The same parameter shape is accepted on the v2 Query endpoint.

Response Shape

v3 returns results, and each result uses text for chunk text.

1{
2 "query": "What evidence supports the safety claim?",
3 "results": [
4 {
5 "chunk_id": "chk_abc123_004",
6 "text": "Patients receiving therapy reported no treatment-related serious adverse events.",
7 "score": 0.92,
8 "document": {
9 "id": "doc_abc123",
10 "filename": "study-summary.pdf",
11 "source": null
12 },
13 "metadata": {
14 "review_state": "approved"
15 },
16 "custom_metadata": {
17 "claim_type": "safety"
18 },
19 "relations": [],
20 "related_chunks": []
21 }
22 ],
23 "total_results": 1,
24 "limit": 10
25}

Use Advanced Search & Relations for metadata filters, chunk custom_metadata, region data, relations, and relation-aware queries.

Cap a Document’s Share of Results

limit counts chunks, not documents, so one long file can occupy the whole result page. max_chunks_per_document drops a document’s surplus chunks and backfills the page with the next best chunks from other documents. Ranking is unchanged; only the page composition is.

1{
2 "query": "termination clauses and notice periods",
3 "limit": 10,
4 "max_chunks_per_document": 2
5}

Return the Top Documents

top_documents: N answers “give me the N most relevant documents”. The response gains a top_documents array ranking documents by their best chunk across the whole ranked pool (which is deeper than the page). This is a document-level view of the ranking, not to be confused with include.document, which only attaches each chunk’s parent-document info to the flat results. The flat results list is unaffected (and stays byte-identical whether top documents are requested or not), and the top-level limit keeps counting chunks.

1{
2 "query": "termination clauses and notice periods",
3 "limit": 10,
4 "max_chunks_per_document": 2,
5 "top_documents": 5
6}
1{
2 "top_documents": [
3 {
4 "document_id": "doc_9f2c41",
5 "file_id": "3b9cb67f",
6 "filename": "master-services-agreement.pdf",
7 "score": 0.91,
8 "chunk_count": 14,
9 "chunks": [
10 { "chunk_id": "chk_abc123_004", "score": 0.91 },
11 { "chunk_id": "chk_abc123_011", "score": 0.84 }
12 ]
13 }
14 ]
15}

Each entry’s document_id is the stable identifier: it works with Get Document and survives re-indexing, unlike the per-generation file_id. chunk_count reports how many of the document’s chunks appeared in the ranked pool, and chunks lists every one of its chunks that made results, ranked by score, so each reference resolves by chunk_id. A document can rank on pool evidence alone and carry an empty chunks list; max_chunks_per_document keeps the page diverse enough that every top document surfaces its chunks. Both options compose with reranking, boosts, and relations.

Documents and Chunks

Use document and chunk endpoints when your application needs stable source objects outside the search response:

These endpoints are useful for citations, review flows, and source-grounded UI state.

v2 Compatibility

Existing v2 clients should continue using v2 Query. v2 keeps the old field names:

1{
2 "search_results": [
3 {
4 "content": "Patients receiving therapy reported no treatment-related serious adverse events."
5 }
6 ]
7}

Do not document v3 behavior as v2 behavior. v2 does not return v3 fields such as results, text, custom_metadata, relations, or related_chunks.

© 2026 Captain