> For a complete page index of the Captain API documentation, fetch https://docs.filesearch.dev/llms.txt?excludeSpec=true

# Query - v2 (Legacy)

POST https://api.filesearch.dev/v2/collections/{collection_name}/query
Content-Type: application/json

Execute the v2 File Search endpoint against a collection. Returns retrieved chunks in search_results with content fields.

Reference: https://docs.filesearch.dev/reference/v2/query

## Request

### Path parameters

- `collection_name` (string, required)

### Body (application/json)

This endpoint expects a QueryRequestV2.

- `query` (string, required) — Natural-language search query.
- `top_k` (integer, optional, nullable, default: 10) — Maximum number of search results to return.
- `metadata_filter` (map from string to any, optional, nullable) — Filter expression for indexed document metadata. Supports $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $and, and $or.
- `include_archived` (boolean, optional, default: false) — Include chunks archived by a sync `archive` deletion policy. Archived content is excluded from search by default; set true to surface it.
- `rerank` (QueryRequestV2Rerank, optional, nullable, default: false) — Rerank retrieved candidates before returning the top results (adds roughly 200 ms). Boolean form uses the defaults: voyage-rerank-2.5 over a pool of `limit` x 3 candidates. Object form tunes reranking — see RerankOptions. Multimodal collections default to reranking; an explicit `false` (or `{"enabled": false}`) opts out and returns a warning noting reduced cross-modal ranking quality. On v2, the deprecated `inference=true` path honours only the enabled/disabled state; the tuning fields apply to retrieval queries.
- `include_bbox` (boolean, optional, nullable, default: false) — Legacy v2 layout option retained for clients that already depend on bounding boxes.
- `semantic_ratio` (double, optional, default: 0.5) — Balance between semantic and keyword retrieval. Captain searches both ways at once: keyword (sparse, BM25) matches the words in the query, semantic (dense vector) matches its meaning. 0.0 is keyword only, 1.0 is semantic only, and 0.5 (the default) weighs them equally. Lower it for corpora full of exact terms such as part numbers or error codes; raise it when callers phrase questions in their own words. Between the endpoints both searches run, so a result found only by the down-weighted side still appears, just lower. The endpoints skip the other search entirely: 0.0 also skips embedding the query, making it the fastest option, though queries using `boost` and collections holding images, video, or audio keep vector search running. See the Advanced Querying guide for more.

## Response

### 200

Successful Response

- `success` (boolean, required)
- `query` (string, required)
- `search_results` (list of FileSearchResult, required)
- `total_results` (integer, required)
- `top_k` (integer, required)
- `warnings` (list of string, optional, nullable)
- `tokens_used` (map from string to integer, optional, nullable)
- `execution_time_ms` (integer, optional, nullable)
- `request_id` (string, optional, nullable)
- `query_id` (string, optional, nullable) — Id of this query in your history. Fetch it back with GET /v2/queries/\{query\_id}. Present when the query was stored (completed, non-streamed queries).
- `token_balance` (TokenBalance, optional, nullable)

## Types

### QueryRequestV2Rerank

Rerank retrieved candidates before returning the top results (adds roughly 200 ms). Boolean form uses the defaults: voyage-rerank-2.5 over a pool of `limit` x 3 candidates. Object form tunes reranking — see RerankOptions. Multimodal collections default to reranking; an explicit `false` (or `{"enabled": false}`) opts out and returns a warning noting reduced cross-modal ranking quality. On v2, the deprecated `inference=true` path honours only the enabled/disabled state; the tuning fields apply to retrieval queries.

- boolean
- Rerank Options: RerankOptions

### FileSearchResult

A v2 compatibility File Search result chunk.

- `score` (double, required)
- `content` (string, required) — Retrieved chunk text. v3 uses text instead.
- `document_id` (string, optional, nullable)
- `filename` (string, optional, nullable)
- `uri` (string, optional, nullable)
- `chunk_index` (integer, optional, nullable)
- `metadata` (map from string to any, optional, nullable)
- `rerank_score` (double, optional, nullable)

### TokenBalance

- `credit_limit` (integer, required)
- `total_used` (integer, required)
- `remaining` (integer, required)
- `unlimited` (boolean, optional, default: false)

### RerankOptions

Object form of the `rerank` parameter. The boolean form stays valid: `true` is equivalent to sending this object with every field at its default.

- `enabled` (boolean, optional, default: true) — Whether to rerank. Sending the object without this field means enabled — the object form exists to tune reranking.
- `candidate_limit` (integer, optional, nullable) — How many fused retrieval candidates are fetched and reranked before the top `limit` results are returned. Defaults to `limit` x 3 (the measured configuration). Must be >= `limit`; capped at 200. Larger pools can lift recall on corpora with many near-duplicate documents, at the cost of rerank latency.
- `model` (string, optional, nullable) — Reranker model. 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` — higher quality ceiling on complex queries, 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.

## Examples

**Request**

```json
{
  "query": "What are the key terms in the contract?",
  "top_k": 10,
  "rerank": true
}
```

**Response**

```json
{
  "success": true,
  "query": "What are the key terms in the contract?",
  "search_results": [
    {
      "score": 0.92,
      "content": "The contract shall commence on the Effective Date and continue for a period of twelve (12) months.",
      "document_id": "doc_abc123",
      "filename": "contract.pdf",
      "uri": "s3://my-company-docs/contracts/contract.pdf",
      "chunk_index": 3,
      "metadata": {
        "pageStart": 2,
        "pageEnd": 2
      },
      "rerank_score": 0.98
    }
  ],
  "total_results": 1,
  "top_k": 10,
  "warnings": [],
  "tokens_used": {
    "search": 28
  },
  "execution_time_ms": 245,
  "request_id": "req_abc123",
  "query_id": "019a0e2a-7b31-7c4e-9d2f-3a8c1e5b6f90"
}
```

**SDK Code**

```python Python REST
import requests
import uuid
import json

BASE_URL = "https://api.filesearch.dev"
API_KEY = "your_api_key"
COLLECTION_NAME = "my_documents"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
    "Idempotency-Key": str(uuid.uuid4()),
}

response = requests.post(
    f"{BASE_URL}/v2/collections/{COLLECTION_NAME}/query",
    headers=headers,
    json={
        "query": "What are the key terms in the contract?",
        "top_k": 10,
        "rerank": True,
    },
    timeout=120.0,
)

print(json.dumps(response.json(), indent=2))
```

```typescript TypeScript REST
const BASE_URL = "https://api.filesearch.dev";
const API_KEY = "your_api_key";
const collectionName = "my_documents";

const response = await fetch(`${BASE_URL}/v2/collections/${collectionName}/query`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    query: "What are the key terms in the contract?",
    top_k: 10,
    rerank: true,
  }),
});

const result = await response.json();
console.log(JSON.stringify(result, null, 2));
```