> For the complete documentation index, see [llms.txt](https://docs.qolaba.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.qolaba.ai/api-platform/openai-compatible-chat/built-in-tools/file-search.md).

# File Search

Upload files and search through them using RAG. Upload documents via the Files API, then reference stores in chat completions via file\_search\_store\_names.

The `file_search` tool is a **built-in tool** for searching through your uploaded documents. Unlike `internet_search` (live web) and `url_content` (public URLs), this tool searches **your private uploaded files** stored in a **File Search Store**. It uses **Google Gemini 2.5 Flash** with native `fileSearch` grounding to retrieve and answer from document content.

### How It Works

1. Upload documents to a **File Search Store** via `POST /api/v1/files`
2. Pass the returned store name(s) in the `file_search_store_names` field of your chat request
3. The LLM receives the store names via an injected system message and calls the `file_search` tool automatically
4. Gemini 2.5 Flash searches the store using semantic/vector search and returns grounded answers with citations
5. The answer is returned as a standard chat completion

#### Key Difference from Other Tools

| Tool              | Trigger                                     | Source                              |
| ----------------- | ------------------------------------------- | ----------------------------------- |
| `internet_search` | Auto (from prompt)                          | Live public web via Perplexity      |
| `url_content`     | Auto (URL in message)                       | Specific public URL via Gemini      |
| `file_search`     | Auto + `file_search_store_names` in request | **Your private uploaded documents** |

***

### Step 1: Upload Files

Upload a document by URL to create a file search store.

**Endpoint:** `POST /api/v1/files`

**Auth:** Required (`X-API-Key` or `Authorization: Bearer`)\
**Timeout:** 5 minutes

#### Request Body

| Parameter    | Type   | Required | Description                                                                    |
| ------------ | ------ | -------- | ------------------------------------------------------------------------------ |
| `url`        | string | ✅        | Public URL to the file                                                         |
| `store_name` | string | —        | Custom name for the vector store. If omitted, a store is created automatically |

#### Supported File Types

| Extension | MIME Type                                                                 |
| --------- | ------------------------------------------------------------------------- |
| `.pdf`    | `application/pdf`                                                         |
| `.txt`    | `text/plain`                                                              |
| `.doc`    | `application/msword`                                                      |
| `.docx`   | `application/vnd.openxmlformats-officedocument.wordprocessingml.document` |

#### Upload Request

```bash
curl -X POST https://api.platform.qolaba.ai/api/v1/files \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "url": "https://example.com/document.pdf",
    "store_name": "my-store"
  }'
```

#### Upload Response `200 OK`

```json
{
  "success": true,
  "store_name": "fileSearchStores/my-store-31ihhh9rmyef",
  "file_name": "document.pdf",
  "message": "File uploaded and indexed successfully",
  "token_count": 4200,
  "estimated_cost_usd": 0.0021,
  "creditUtilisation": 2
}
```

| Field                | Type    | Description                                                                                      |
| -------------------- | ------- | ------------------------------------------------------------------------------------------------ |
| `success`            | boolean | Whether the upload succeeded                                                                     |
| `store_name`         | string  | Vector store name in `fileSearchStores/{storeId}` format — use this in `file_search_store_names` |
| `file_name`          | string  | Name of the uploaded file                                                                        |
| `message`            | string  | Status message                                                                                   |
| `token_count`        | integer | Number of tokens indexed from the file                                                           |
| `estimated_cost_usd` | number  | Estimated cost in USD                                                                            |
| `creditUtilisation`  | number  | Credits consumed for this upload                                                                 |

#### Upload Error `400 Bad Request`

```json
{
  "success": false,
  "message": "File type '.csv' is not supported. Allowed types: .pdf, .txt, .doc, .docx",
  "error": "File type '.csv' is not supported. Allowed types: .pdf, .txt, .doc, .docx"
}
```

***

### Step 2: Search Your Files

Pass the `store_name` from the upload response into `file_search_store_names` in your chat completion request. The model will automatically search the store when the prompt is relevant.

#### Use Cases & Examples

#### 1. Summarize an Uploaded Document

```json
{
  "model": "google/gemini-2.5-flash",
  "file_search_store_names": ["fileSearchStores/my-store-31ihhh9rmyef"],
  "messages": [
    { "role": "user", "content": "Summarize the uploaded document" }
  ]
}
```

#### 2. Compare Multiple Document Collections

```json
{
  "model": "google/gemini-2.5-flash",
  "file_search_store_names": [
    "fileSearchStores/q1-reports",
    "fileSearchStores/q2-reports"
  ],
  "messages": [
    { "role": "user", "content": "Compare Q1 and Q2 revenue figures from the reports" }
  ]
}
```

#### 3. Contract / Legal Document Analysis

```json
{
  "model": "google/gemini-2.5-flash",
  "file_search_store_names": ["fileSearchStores/contracts-store"],
  "messages": [
    { "role": "user", "content": "What are the termination clauses in the uploaded contract?" }
  ]
}
```

#### 4. With a System Prompt

```json
{
  "model": "google/gemini-2.5-flash",
  "file_search_store_names": ["fileSearchStores/support-docs"],
  "messages": [
    {
      "role": "system",
      "content": "You are a helpful support agent. Only answer based on the uploaded documentation."
    },
    { "role": "user", "content": "How do I upgrade my plan?" }
  ]
}
```

### Tips & Best Practices

| Tip                            | Details                                                                                 |
| ------------------------------ | --------------------------------------------------------------------------------------- |
| **Always pass store names**    | `file_search_store_names` must be in every request — the tool won't activate without it |
| **Pass on every turn**         | In multi-turn conversations, include the field on each request                          |
| **Multiple stores**            | Pass an array to search across multiple document collections at once                    |
| **Any model works**            | Store names are injected as a system message — model-agnostic                           |
| **Be specific**                | "What is the refund policy?" retrieves more precisely than "Tell me about the document" |
| **Combine with system prompt** | Use a system prompt to constrain the model to only answer from the documents            |

***

### Limitations

* **Supported file types** — only `.pdf`, `.txt`, `.doc`, and `.docx` files can be uploaded
* **Store names are static** — if a store is deleted or renamed, queries will fail gracefully (returns an error message without crashing)
* **No raw chunk retrieval** — you get a synthesized answer, not a list of raw document excerpts
* **No filtering by file** — all files in the store are searched together; you can't target a specific file within a store
* **`file_search_store_names` is not a standard OpenAI field** — OpenAI SDK clients must use `extra_body` (Python) or `// @ts-ignore` (TypeScript) to pass it
