Repository Public
1The Gemini API enables Retrieval Augmented Generation ("RAG") through the File2Search tool. File Search imports, chunks, and indexes your data to3enable fast retrieval of relevant information based on a provided prompt. This4retrieved information is then used as context for the model, allowing it to5provide more accurate and relevant answers. File search is also able to6provide multimodal capabilities with text embeddings supported by7`gemini-embedding-001`, and image/multimodal embedding supported by `gemini-embedding-2`.89> [!NOTE]10> **Note:** Audio and video formats are not currently supported.1112File storage and embedding generation at query time is free, and you'll only pay13for creating embeddings when you first index your files and the normal Gemini14model input / output tokens cost. This new billing paradigm makes the File15Search Tool both easier and more cost-effective to build and scale with. See16[pricing](https://ai.google.dev/gemini-api/docs/file-search#pricing) section for details.1718## Directly upload to File Search store1920This example shows how to directly upload a file to the21[file search store](https://ai.google.dev/api/file-search/file-search-stores#method:-media.uploadtofilesearchstore):2223### Python2425 from google import genai26 from google.genai import types27 import time2829 client = genai.Client()3031 file_search_store = client.file_search_stores.create(32 config={33 'display_name': 'your-fileSearchStore-name',34 'embedding_model': 'models/gemini-embedding-2'35 }36 )3738 operation = client.file_search_stores.upload_to_file_search_store(39 file='sample.txt',40 file_search_store_name=file_search_store.name,41 config={42 'display_name' : 'display-file-name',43 }44 )4546 while not operation.done:47 time.sleep(5)48 operation = client.operations.get(operation)4950 interaction = client.interactions.create(51 model="gemini-3.8-flash",52 input="Can you tell me about [insert question]",53 tools=[{54 "type": "file_search",55 "file_search_store_names": [file_search_store.name]56 }]57 )5859 for step in interaction.steps:60 if step.type == "model_output":61 for content_block in step.content:62 if content_block.type == "text":63 print(content_block.text)64 if content_block.annotations:65 print("\nSources:")66 for annotation in content_block.annotations:67 if annotation.type == "file_citation":68 print(f" - {annotation.file_name}: {annotation.source}")6970### JavaScript7172 import { GoogleGenAI } from '@google/genai';7374 const ai = new GoogleGenAI({});7576 async function run() {77 const fileSearchStore = await ai.fileSearchStores.create({78 config: {79 displayName: 'your-fileSearchStore-name',80 embeddingModel: 'models/gemini-embedding-2'81 }82 });8384 let operation = await ai.fileSearchStores.uploadToFileSearchStore({85 file: 'file.txt',86 fileSearchStoreName: fileSearchStore.name,87 config: {88 displayName: 'file-name',89 }90 });9192 while (!operation.done) {93 await new Promise(resolve => setTimeout(resolve, 5000));94 operation = await ai.operations.get({ operation });95 }9697 const interaction = await ai.interactions.create({98 model: "gemini-3.8-flash",99 input: "Can you tell me about [insert question]",100 tools: [{101 type: "file_search",102 file_search_store_names: [fileSearchStore.name]103 }]104 });105106 for (const step of interaction.steps) {107 if (step.type === 'model_output') {108 for (const contentBlock of step.content) {109 if (contentBlock.type === 'text') {110 console.log(contentBlock.text);111 if (contentBlock.annotations) {112 console.log("\nSources:");113 for (const annotation of contentBlock.annotations) {114 if (annotation.type === 'file_citation') {115 console.log(` - ${annotation.file_name}: ${annotation.source}`);116 }117 }118 }119 }120 }121 }122 }123 }124125 run();126127### Java128129 import com.google.genai.Client;130 import com.google.genai.gaos.models.interactions.Annotation;131 import com.google.genai.gaos.models.interactions.Content;132 import com.google.genai.gaos.models.interactions.CreateModelInteraction;133 import com.google.genai.gaos.models.interactions.FileCitation;134 import com.google.genai.gaos.models.interactions.FileSearch;135 import com.google.genai.gaos.models.interactions.Interaction;136 import com.google.genai.gaos.models.interactions.InteractionsInput;137 import com.google.genai.gaos.models.interactions.Model;138 import com.google.genai.gaos.models.interactions.ModelOutputStep;139 import com.google.genai.gaos.models.interactions.Step;140 import com.google.genai.gaos.models.interactions.TextContent;141 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;142 import com.google.genai.types.CreateFileSearchStoreConfig;143 import com.google.genai.types.FileSearchStore;144 import com.google.genai.types.UploadToFileSearchStoreConfig;145 import com.google.genai.types.UploadToFileSearchStoreOperation;146 import java.util.Arrays;147148 Client client = new Client();149150 FileSearchStore fileSearchStore =151 client.fileSearchStores.create(152 CreateFileSearchStoreConfig.builder()153 .displayName("your-fileSearchStore-name")154 .embeddingModel("models/gemini-embedding-2")155 .build());156157 UploadToFileSearchStoreOperation operation =158 client.fileSearchStores.uploadToFileSearchStore(159 fileSearchStore.name().get(),160 "sample.txt",161 UploadToFileSearchStoreConfig.builder().displayName("display-file-name").build());162163 while (!operation.done().orElse(false)) {164 Thread.sleep(5000);165 operation = client.operations.get(operation, null);166 }167168 CreateModelInteraction params =169 CreateModelInteraction.builder()170 .model(Model.of("gemini-3.8-flash"))171 .input(InteractionsInput.of("Can you tell me about [insert question]"))172 .tools(173 Arrays.asList(174 FileSearch.builder()175 .fileSearchStoreNames(Arrays.asList(fileSearchStore.name().get()))176 .build()))177 .build();178179 Interaction interaction =180 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();181182 if (interaction.steps().isPresent()) {183 for (Step step : interaction.steps().get()) {184 if (step instanceof ModelOutputStep) {185 ModelOutputStep outputStep = (ModelOutputStep) step;186 if (outputStep.content().isPresent()) {187 for (Content contentBlock : outputStep.content().get()) {188 if (contentBlock instanceof TextContent) {189 TextContent textContent = (TextContent) contentBlock;190 System.out.println(textContent.text().orElse(""));191 if (textContent.annotations().isPresent()192 && !textContent.annotations().get().isEmpty()) {193 System.out.println("\nSources:");194 for (Annotation annotation : textContent.annotations().get()) {195 if (annotation instanceof FileCitation) {196 FileCitation citation = (FileCitation) annotation;197 System.out.printf(198 " - %s: %s%n",199 citation.fileName().orElse(""), citation.source().orElse(""));200 }201 }202 }203 }204 }205 }206 }207 }208 }209210### REST211212 # 1. Create a File Search store213 curl -X POST "https://generativelanguage.googleapis.com/v1beta/fileSearchStores?key=$GEMINI_API_KEY" \214 -H "Content-Type: application/json" \215 -d '{216 "displayName": "your-file-search-store-name",217 "embeddingModel": "models/gemini-embedding-2"218 }' > store_res.json219220 FILE_SEARCH_STORE_NAME=$(jq -r ".name" store_res.json)221222 # 2. Upload directly to File Search store using resumable upload223 NUM_BYTES=$(wc -c < "sample.txt")224 curl "https://generativelanguage.googleapis.com/upload/v1beta/fileSearchStores/$FILE_SEARCH_STORE_NAME:uploadToFileSearchStore?key=$GEMINI_API_KEY" \225 -D upload-header.tmp \226 -H "X-Goog-Upload-Protocol: resumable" \227 -H "X-Goog-Upload-Command: start" \228 -H "X-Goog-Upload-Header-Content-Length: $NUM_BYTES" \229 -H "X-Goog-Upload-Header-Content-Type: text/plain" \230 -H "Content-Type: application/json" \231 -d '{"displayName": "sample.txt"}' 2> /dev/null232233 upload_url=$(grep -i "x-goog-upload-url: " upload-header.tmp | cut -d" " -f2 | tr -d "\r")234 rm upload-header.tmp235236 curl "${upload_url}" \237 -H "Content-Length: $NUM_BYTES" \238 -H "X-Goog-Upload-Offset: 0" \239 -H "X-Goog-Upload-Command: upload, finalize" \240 --data-binary "@sample.txt" 2> /dev/null > upload_response.json241242 cat upload_response.json243244 # 3. Query using the File Search store245 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \246 -H "x-goog-api-key: $GEMINI_API_KEY" \247 -H "Content-Type: application/json" \248 -d '{249 "model": "gemini-3.8-flash",250 "input": "Can you tell me about [insert question]",251 "tools": [{252 "type": "file_search",253 "file_search_store_names": ["'"$FILE_SEARCH_STORE_NAME"'"]254 }]255 }'256257Check the API reference for [`uploadToFileSearchStore`](https://ai.google.dev/api/file-search/file-search-stores#method:-media.uploadtofilesearchstore) for more information.258259## Importing files260261Alternatively, you can upload an existing file and [import it to your file search store](https://ai.google.dev/api/file-search/file-search-stores#method:-filesearchstores.importfile):262263### Python264265 from google import genai266 from google.genai import types267 import time268269 client = genai.Client()270271 sample_file = client.files.upload(file='sample.txt', config={'display_name': 'display_file_name'})272273 file_search_store = client.file_search_stores.create(274 config={275 'display_name': 'your-fileSearchStore-name',276 'embedding_model': 'models/gemini-embedding-2'277 }278 )279280 operation = client.file_search_stores.import_file(281 file_search_store_name=file_search_store.name,282 file_name=sample_file.name283 )284285 while not operation.done:286 time.sleep(5)287 operation = client.operations.get(operation)288289 interaction = client.interactions.create(290 model="gemini-3.8-flash",291 input="Can you tell me about [insert question]",292 tools=[{293 "type": "file_search",294 "file_search_store_names": [file_search_store.name]295 }]296 )297298 for step in interaction.steps:299 if step.type == "model_output":300 for content_block in step.content:301 if content_block.type == "text":302 print(content_block.text)303304### JavaScript305306 import { GoogleGenAI } from '@google/genai';307308 const ai = new GoogleGenAI({});309310 async function run() {311 const sampleFile = await ai.files.upload({312 file: 'sample.txt',313 config: { displayName: 'file-name' }314 });315316 const fileSearchStore = await ai.fileSearchStores.create({317 config: {318 displayName: 'your-fileSearchStore-name',319 embeddingModel: 'models/gemini-embedding-2'320 }321 });322323 let operation = await ai.fileSearchStores.importFile({324 fileSearchStoreName: fileSearchStore.name,325 fileName: sampleFile.name326 });327328 while (!operation.done) {329 await new Promise(resolve => setTimeout(resolve, 5000));330 operation = await ai.operations.get({ operation: operation });331 }332333 const interaction = await ai.interactions.create({334 model: "gemini-3.8-flash",335 input: "Can you tell me about [insert question]",336 tools: [{337 type: "file_search",338 file_search_store_names: [fileSearchStore.name]339 }]340 });341342 for (const step of interaction.steps) {343 if (step.type === 'model_output') {344 for (const contentBlock of step.content) {345 if (contentBlock.type === 'text') {346 console.log(contentBlock.text);347 }348 }349 }350 }351 }352353 run();354355### Java356357 import com.google.genai.Client;358 import com.google.genai.gaos.models.interactions.Content;359 import com.google.genai.gaos.models.interactions.CreateModelInteraction;360 import com.google.genai.gaos.models.interactions.FileSearch;361 import com.google.genai.gaos.models.interactions.Interaction;362 import com.google.genai.gaos.models.interactions.InteractionsInput;363 import com.google.genai.gaos.models.interactions.Model;364 import com.google.genai.gaos.models.interactions.ModelOutputStep;365 import com.google.genai.gaos.models.interactions.Step;366 import com.google.genai.gaos.models.interactions.TextContent;367 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;368 import com.google.genai.types.CreateFileSearchStoreConfig;369 import com.google.genai.types.File;370 import com.google.genai.types.FileSearchStore;371 import com.google.genai.types.ImportFileOperation;372 import com.google.genai.types.UploadFileConfig;373 import java.util.Arrays;374375 Client client = new Client();376377 File sampleFile =378 client.files.upload(379 "sample.txt", UploadFileConfig.builder().displayName("display_file_name").build());380381 FileSearchStore fileSearchStore =382 client.fileSearchStores.create(383 CreateFileSearchStoreConfig.builder()384 .displayName("your-fileSearchStore-name")385 .embeddingModel("models/gemini-embedding-2")386 .build());387388 ImportFileOperation operation =389 client.fileSearchStores.importFile(390 fileSearchStore.name().get(), sampleFile.name().get(), null);391392 while (!operation.done().orElse(false)) {393 Thread.sleep(5000);394 operation = client.operations.get(operation, null);395 }396397 CreateModelInteraction params =398 CreateModelInteraction.builder()399 .model(Model.of("gemini-3.8-flash"))400 .input(InteractionsInput.of("Can you tell me about [insert question]"))401 .tools(402 Arrays.asList(403 FileSearch.builder()404 .fileSearchStoreNames(Arrays.asList(fileSearchStore.name().get()))405 .build()))406 .build();407408 Interaction interaction =409 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();410411 if (interaction.steps().isPresent()) {412 for (Step step : interaction.steps().get()) {413 if (step instanceof ModelOutputStep) {414 ModelOutputStep outputStep = (ModelOutputStep) step;415 if (outputStep.content().isPresent()) {416 for (Content contentBlock : outputStep.content().get()) {417 if (contentBlock instanceof TextContent) {418 TextContent textContent = (TextContent) contentBlock;419 System.out.println(textContent.text().orElse(""));420 }421 }422 }423 }424 }425 }426427### REST428429 # 1. Upload file using the Files API430 NUM_BYTES=$(wc -c < "sample.txt")431 curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=$GEMINI_API_KEY" \432 -D upload-header.tmp \433 -H "X-Goog-Upload-Protocol: resumable" \434 -H "X-Goog-Upload-Command: start" \435 -H "X-Goog-Upload-Header-Content-Length: $NUM_BYTES" \436 -H "X-Goog-Upload-Header-Content-Type: text/plain" \437 -H "Content-Type: application/json" \438 -d '{"file": {"displayName": "sample.txt"}}' 2> /dev/null439440 upload_url=$(grep -i "x-goog-upload-url: " upload-header.tmp | cut -d" " -f2 | tr -d "\r")441 rm upload-header.tmp442443 curl "${upload_url}" \444 -H "Content-Length: $NUM_BYTES" \445 -H "X-Goog-Upload-Offset: 0" \446 -H "X-Goog-Upload-Command: upload, finalize" \447 --data-binary "@sample.txt" 2> /dev/null > file_info.json448449 FILE_NAME=$(jq -r ".file.name" file_info.json)450451 # 2. Create a File Search store452 curl -X POST "https://generativelanguage.googleapis.com/v1beta/fileSearchStores?key=$GEMINI_API_KEY" \453 -H "Content-Type: application/json" \454 -d '{455 "displayName": "your-file-search-store-name",456 "embeddingModel": "models/gemini-embedding-2"457 }' > store_res.json458459 FILE_SEARCH_STORE_NAME=$(jq -r ".name" store_res.json)460461 # 3. Import the file into the File Search store462 curl -X POST "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/$FILE_SEARCH_STORE_NAME:importFile?key=$GEMINI_API_KEY" \463 -H "Content-Type: application/json" \464 -d '{"fileName": "'"$FILE_NAME"'"}'465466 # 4. Query using the File Search store467 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \468 -H "x-goog-api-key: $GEMINI_API_KEY" \469 -H "Content-Type: application/json" \470 -d '{471 "model": "gemini-3.8-flash",472 "input": "Can you tell me about [insert question]",473 "tools": [{474 "type": "file_search",475 "file_search_store_names": ["'"$FILE_SEARCH_STORE_NAME"'"]476 }]477 }'478479Check the API reference for [`importFile`](https://ai.google.dev/api/file-search/file-search-stores#method:-filesearchstores.importfile) for more information.480481## Chunking configuration482483When you import a file into a File Search store, it's automatically broken down484into chunks, embedded, indexed, and uploaded to your File Search store. If you485need more control over the chunking strategy, you can specify a486[`chunking_config`](https://ai.google.dev/api/file-search/file-search-stores#request-body_5) setting487to set a maximum number of tokens per chunk and maximum number of overlapping488tokens.489490### Python491492 from google import genai493 from google.genai import types494 import time495496 client = genai.Client()497498 operation = client.file_search_stores.upload_to_file_search_store(499 file_search_store_name=file_search_store.name,500 file='sample.txt',501 config={502 'chunking_config': {503 'white_space_config': {504 'max_tokens_per_chunk': 200,505 'max_overlap_tokens': 20506 }507 }508 }509 )510511 while not operation.done:512 time.sleep(5)513 operation = client.operations.get(operation)514515 print("Custom chunking complete.")516517### JavaScript518519 import { GoogleGenAI } from '@google/genai';520521 const ai = new GoogleGenAI({});522523 let operation = await ai.fileSearchStores.uploadToFileSearchStore({524 file: 'file.txt',525 fileSearchStoreName: fileSearchStore.name,526 config: {527 displayName: 'file-name',528 chunkingConfig: {529 whiteSpaceConfig: {530 maxTokensPerChunk: 200,531 maxOverlapTokens: 20532 }533 }534 }535 });536537 while (!operation.done) {538 await new Promise(resolve => setTimeout(resolve, 5000));539 operation = await ai.operations.get({ operation });540 }541 console.log("Custom chunking complete.");542543### Java544545 import com.google.genai.Client;546 import com.google.genai.types.ChunkingConfig;547 import com.google.genai.types.UploadToFileSearchStoreConfig;548 import com.google.genai.types.UploadToFileSearchStoreOperation;549 import com.google.genai.types.WhiteSpaceConfig;550551 Client client = new Client();552553 UploadToFileSearchStoreOperation operation =554 client.fileSearchStores.uploadToFileSearchStore(555 "fileSearchStores/my-file-search-store",556 "sample.txt",557 UploadToFileSearchStoreConfig.builder()558 .displayName("file-name")559 .chunkingConfig(560 ChunkingConfig.builder()561 .whiteSpaceConfig(562 WhiteSpaceConfig.builder()563 .maxTokensPerChunk(200)564 .maxOverlapTokens(20)565 .build())566 .build())567 .build());568569 while (!operation.done().orElse(false)) {570 Thread.sleep(5000);571 operation = client.operations.get(operation, null);572 }573574 System.out.println("Custom chunking complete.");575576### REST577578 NUM_BYTES=$(wc -c < "sample.txt")579 curl "https://generativelanguage.googleapis.com/upload/v1beta/fileSearchStores/$FILE_SEARCH_STORE_NAME:uploadToFileSearchStore?key=$GEMINI_API_KEY" \580 -D upload-header.tmp \581 -H "X-Goog-Upload-Protocol: resumable" \582 -H "X-Goog-Upload-Command: start" \583 -H "X-Goog-Upload-Header-Content-Length: $NUM_BYTES" \584 -H "X-Goog-Upload-Header-Content-Type: text/plain" \585 -H "Content-Type: application/json" \586 -d '{587 "displayName": "sample.txt",588 "chunkingConfig": {589 "whiteSpaceConfig": {590 "maxTokensPerChunk": 200,591 "maxOverlapTokens": 20592 }593 }594 }' 2> /dev/null595596 upload_url=$(grep -i "x-goog-upload-url: " upload-header.tmp | cut -d" " -f2 | tr -d "\r")597 rm upload-header.tmp598599 curl "${upload_url}" \600 -H "Content-Length: $NUM_BYTES" \601 -H "X-Goog-Upload-Offset: 0" \602 -H "X-Goog-Upload-Command: upload, finalize" \603 --data-binary "@sample.txt" 2> /dev/null > upload_response.json604605 cat upload_response.json606607To use your File Search store, pass it as a tool to the `interactions.create`608method, as shown in the [Upload](https://ai.google.dev/gemini-api/docs/file-search#upload) and [Import](https://ai.google.dev/gemini-api/docs/file-search#importing-files) examples.609610## How it works611612File Search uses a technique called semantic search to find information relevant613to the user prompt. Unlike standard keyword-based search, semantic search614understands the meaning and context of your query.615616When you import a file, it's converted into numerical representations called617[embeddings](https://ai.google.dev/gemini-api/docs/embeddings), which capture the semantic meaning of618the uploaded content. These embeddings are stored in a specialized File Search database.619When you make a query, it's also converted into an embedding. Then the system620performs a File Search to find the most similar and relevant document chunks621from the File Search store.622623There is no Time To Live (TTL) for embeddings;624they persist until manually deleted, or when the model is deprecated. Files,625however, are deleted after 48 hours.626627Here's a breakdown of the process for using the File Search628`uploadToFileSearchStore` API:6296301. **Create a File Search store**: A File Search store contains the processed631 data from your files. It's the persistent container for the embeddings that the632 semantic search will operate on.6336342. **Upload a file and import into a File Search store** : Simultaneously upload635 a file and import the results into your File Search store. This creates a636 temporary `File` object, which is a reference to your raw document. That data is637 then chunked, converted into File Search embeddings, and indexed. The `File`638 object gets deleted after 48 hours, while the data imported into the File Search639 store will be stored indefinitely until you choose to delete it.6406413. **Query with File Search** : Finally, you use the `FileSearch` tool in a642 `generateContent` call. In the tool configuration, you specify a643 `FileSearchRetrievalResource`, which points to the `FileSearchStore` you want to644 search. This tells the model to perform a semantic search on that specific645 File Search store to find relevant information to ground its response.646647 The indexing and querying process of File Search648649In this diagram, the dotted line from *Documents* to *Embedding model*650(using [`gemini-embedding-001`](https://ai.google.dev/gemini-api/docs/embeddings))651represents the `uploadToFileSearchStore` API (bypassing *File storage* ).652Otherwise, using the [Files API](https://ai.google.dev/gemini-api/docs/files) to separately create653and then import files moves the indexing process from *Documents* to654*File storage* and then to *Embedding model*.655656## File Search stores657658A File Search store is a container for your document embeddings. While raw files659uploaded through the File API are deleted after 48 hours, the data imported into660a File Search store is stored indefinitely until you manually delete it. You can661create multiple File Search stores to organize your documents. The662`FileSearchStore` API lets you create, list, get, and delete to manage your file663search stores. File Search store names are globally scoped.664665Here are some examples of how to manage your File Search stores:666667### Python668669 file_search_store = client.file_search_stores.create(670 config={671 'display_name': 'myfilesearchstore123',672 'embedding_model': 'models/gemini-embedding-2'673 }674 )675676 for store in client.file_search_stores.list():677 print(store)678679 my_file_search_store = client.file_search_stores.get(name=file_search_store.name)680681 client.file_search_stores.delete(name=file_search_store.name, config={'force': True})682683### JavaScript684685 const fileSearchStore = await ai.fileSearchStores.create({686 config: {687 displayName: 'myfilesearchstore123',688 embeddingModel: 'models/gemini-embedding-2'689 }690 });691692 const fileSearchStores = await ai.fileSearchStores.list();693 for await (const store of fileSearchStores) {694 console.log(store);695 }696697 const myFileSearchStore = await ai.fileSearchStores.get({698 name: fileSearchStore.name699 });700701 await ai.fileSearchStores.delete({702 name: fileSearchStore.name,703 config: { force: true }704 });705706### Java707708 import com.google.genai.Client;709 import com.google.genai.types.CreateFileSearchStoreConfig;710 import com.google.genai.types.DeleteFileSearchStoreConfig;711 import com.google.genai.types.FileSearchStore;712713 Client client = new Client();714715 FileSearchStore fileSearchStore =716 client.fileSearchStores.create(717 CreateFileSearchStoreConfig.builder()718 .displayName("myfilesearchstore123")719 .embeddingModel("models/gemini-embedding-2")720 .build());721722 for (FileSearchStore store : client.fileSearchStores.list(null)) {723 System.out.println(store);724 }725726 FileSearchStore myFileSearchStore =727 client.fileSearchStores.get(fileSearchStore.name().get(), null);728729 client.fileSearchStores.delete(730 fileSearchStore.name().get(), DeleteFileSearchStoreConfig.builder().force(true).build());731732### REST733734 curl -X POST "https://generativelanguage.googleapis.com/v1beta/fileSearchStores?key=${GEMINI_API_KEY}" \735 -H "Content-Type: application/json" \736 -d '{ "displayName": "My Store", "embedding_model": "models/gemini-embedding-2" }'737738 curl "https://generativelanguage.googleapis.com/v1beta/fileSearchStores?key=${GEMINI_API_KEY}"739740 curl "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/myfilesearchstore123?key=${GEMINI_API_KEY}"741742 curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/myfilesearchstore123?key=${GEMINI_API_KEY}"743744## File Search documents745746You can manage individual documents in your file stores with the747[File Search Documents](https://ai.google.dev/api/file-search/documents) API to `list` each document748in a file search store, `get` information about a document, and `delete` a749document by name.750751### Python752753 for document_in_store in client.file_search_stores.documents.list(parent='fileSearchStores/myfilesearchstore123'):754 print(document_in_store)755756 file_search_document = client.file_search_stores.documents.get(name='fileSearchStores/myfilesearchstore123/documents/sampletxt123')757 print(file_search_document)758759 client.file_search_stores.documents.delete(name='fileSearchStores/myfilesearchstore123/documents/sampletxt123', config={'force': True})760761### JavaScript762763 const documents = await ai.fileSearchStores.documents.list({764 parent: 'fileSearchStores/myfilesearchstore123'765 });766 for await (const doc of documents) {767 console.log(doc);768 }769770 const fileSearchDocument = await ai.fileSearchStores.documents.get({771 name: 'fileSearchStores/myfilesearchstore123/documents/sampletxt123'772 });773774 await ai.fileSearchStores.documents.delete({775 name: 'fileSearchStores/myfilesearchstore123/documents/sampletxt123',776 config: { force: true }777 });778779### Java780781 import com.google.genai.Client;782 import com.google.genai.types.DeleteDocumentConfig;783 import com.google.genai.types.Document;784785 Client client = new Client();786787 for (Document documentInStore :788 client.fileSearchStores.documents.list("fileSearchStores/myfilesearchstore123", null)) {789 System.out.println(documentInStore);790 }791792 Document fileSearchDocument =793 client.fileSearchStores.documents.get(794 "fileSearchStores/myfilesearchstore123/documents/sampletxt123", null);795 System.out.println(fileSearchDocument);796797 client.fileSearchStores.documents.delete(798 "fileSearchStores/myfilesearchstore123/documents/sampletxt123",799 DeleteDocumentConfig.builder().force(true).build());800801### REST802803 curl "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/myfilesearchstore123/documents?key=${GEMINI_API_KEY}"804805 curl "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/myfilesearchstore123/documents/sampletxt123?key=${GEMINI_API_KEY}"806807 curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/fileSearchStores/myfilesearchstore123/documents/sampletxt123?key=${GEMINI_API_KEY}&force=true"808809## File metadata810811You can add custom metadata to your files to help filter them or provide812additional context. Metadata is a set of key-value pairs.813814### Python815816 op = client.file_search_stores.import_file(817 file_search_store_name=file_search_store.name,818 file_name=sample_file.name,819 config={820 'custom_metadata': [821 {"key": "author", "string_value": "Robert Graves"},822 {"key": "year", "numeric_value": 1934}823 ]824 }825 )826827### JavaScript828829 let operation = await ai.fileSearchStores.importFile({830 fileSearchStoreName: fileSearchStore.name,831 fileName: sampleFile.name,832 config: {833 customMetadata: [834 { key: "author", stringValue: "Robert Graves" },835 { key: "year", numericValue: 1934 }836 ]837 }838 });839840### Java841842 import com.google.genai.Client;843 import com.google.genai.types.CustomMetadata;844 import com.google.genai.types.ImportFileConfig;845 import com.google.genai.types.ImportFileOperation;846 import java.util.Arrays;847848 Client client = new Client();849850 ImportFileOperation op =851 client.fileSearchStores.importFile(852 "fileSearchStores/myfilesearchstore123",853 "files/samplefile123",854 ImportFileConfig.builder()855 .customMetadata(856 Arrays.asList(857 CustomMetadata.builder().key("author").stringValue("Robert Graves").build(),858 CustomMetadata.builder().key("year").numericValue(1934f).build()))859 .build());860861This is useful when you have multiple documents in a File Search store and want862to search only a subset of them.863864### Python865866 interaction = client.interactions.create(867 model="gemini-3.8-flash",868 input="Tell me about the book 'I, Claudius'",869 tools=[{870 "type": "file_search",871 "file_search_store_names": [file_search_store.name],872 "metadata_filter": 'author="Robert Graves"',873 }]874 )875876 for step in interaction.steps:877 if step.type == "model_output":878 for content_block in step.content:879 if content_block.type == "text":880 print(content_block.text)881882### JavaScript883884 const interaction = await ai.interactions.create({885 model: "gemini-3.8-flash",886 input: "Tell me about the book 'I, Claudius'",887 tools: [{888 type: "file_search",889 file_search_store_names: [fileSearchStore.name],890 metadata_filter: 'author="Robert Graves"',891 }]892 });893894 for (const step of interaction.steps) {895 if (step.type === 'model_output') {896 for (const contentBlock of step.content) {897 if (contentBlock.type === 'text') {898 console.log(contentBlock.text);899 }900 }901 }902 }903904### Java905906 import com.google.genai.Client;907 import com.google.genai.gaos.models.interactions.Content;908 import com.google.genai.gaos.models.interactions.CreateModelInteraction;909 import com.google.genai.gaos.models.interactions.FileSearch;910 import com.google.genai.gaos.models.interactions.Interaction;911 import com.google.genai.gaos.models.interactions.InteractionsInput;912 import com.google.genai.gaos.models.interactions.Model;913 import com.google.genai.gaos.models.interactions.ModelOutputStep;914 import com.google.genai.gaos.models.interactions.Step;915 import com.google.genai.gaos.models.interactions.TextContent;916 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;917 import java.util.Arrays;918919 Client client = new Client();920921 CreateModelInteraction params =922 CreateModelInteraction.builder()923 .model(Model.of("gemini-3.8-flash"))924 .input(InteractionsInput.of("Tell me about the book 'I, Claudius'"))925 .tools(926 Arrays.asList(927 FileSearch.builder()928 .fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))929 .metadataFilter("author=\"Robert Graves\"")930 .build()))931 .build();932933 Interaction interaction =934 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();935936 if (interaction.steps().isPresent()) {937 for (Step step : interaction.steps().get()) {938 if (step instanceof ModelOutputStep) {939 ModelOutputStep outputStep = (ModelOutputStep) step;940 if (outputStep.content().isPresent()) {941 for (Content contentBlock : outputStep.content().get()) {942 if (contentBlock instanceof TextContent) {943 TextContent textContent = (TextContent) contentBlock;944 System.out.println(textContent.text().orElse(""));945 }946 }947 }948 }949 }950 }951952### REST953954 curl "https://generativelanguage.googleapis.com/v1beta/interactions" \955 -H "x-goog-api-key: $GEMINI_API_KEY" \956 -H 'Content-Type: application/json' \957 -X POST \958 -d '{959 "model": "gemini-3.8-flash",960 "input": [{"type": "text", "text": "Tell me about the book I, Claudius"}],961 "tools": [{962 "type": "file_search",963 "file_search_store_names": ["'$STORE_NAME'"],964 "metadata_filter": "author = \"Robert Graves\""965 }]966 }' 2> /dev/null > response.json967968 cat response.json969970Guidance on implementing list filter syntax for `metadata_filter` can be found971at [google.aip.dev/160](https://google.aip.dev/160)972973## Multimodal File Search974975Multimodal File Search lets you to natively embed and search through images,976enabling rich, multimodal RAG applications.977978### Configure the embedding model979980When you create a `FileSearchStore`, you must override the default text-only981embedding model to use a multimodal model. Use `models/gemini-embedding-2` to982process both text and images.983984### Python985986 store = client.file_search_stores.create(987 config={988 "display_name": "Multimodal Catalog",989 "embedding_model": "models/gemini-embedding-2",990 }991 )992993### JavaScript994995 const fileSearchStore = await ai.fileSearchStores.create({996 config: {997 displayName: "Multimodal Catalog",998 embeddingModel: "models/gemini-embedding-2",999 },1000 });10011002### Java10031004 import com.google.genai.Client;1005 import com.google.genai.types.CreateFileSearchStoreConfig;1006 import com.google.genai.types.FileSearchStore;10071008 Client client = new Client();10091010 FileSearchStore store =1011 client.fileSearchStores.create(1012 CreateFileSearchStoreConfig.builder()1013 .displayName("Multimodal Catalog")1014 .embeddingModel("models/gemini-embedding-2")1015 .build());10161017### REST10181019 curl -X POST "https://generativelanguage.googleapis.com/v1beta/fileSearchStores?key=$GEMINI_API_KEY" \1020 -H "Content-Type: application/json" \1021 -d '{1022 "display_name": "Multimodal Catalog",1023 "embedding_model": "models/gemini-embedding-2"1024 }'10251026### Upload images10271028After you create the store with a multimodal embedding model, you can upload1029image files directly using the same upload APIs described in1030[Directly upload to File Search store](https://ai.google.dev/gemini-api/docs/file-search#upload) or [Importing files](https://ai.google.dev/gemini-api/docs/file-search#importing-files).10311032**Image file requirements:**10331034- Image files must be at most 4K x 4K pixels in resolution.1035- Supported formats are PNG, JPEG.10361037## Citations10381039When you use File Search, the model's response may include citations that1040specify which parts of your uploaded documents were used to generate the1041answer. This helps with fact-checking and verification.10421043You can access citation information through the `annotations` attribute inside the `model_output` step's `content` blocks of the response.10441045### Python10461047 for step in interaction.steps:1048 if step.type == 'model_output':1049 for content in step.content:1050 if content.type == 'text' and content.annotations:1051 print(content.annotations)10521053### JavaScript10541055 for (const step of interaction.steps) {1056 if (step.type === 'model_output') {1057 for (const contentBlock of step.content) {1058 if (contentBlock.type === 'text' && contentBlock.annotations) {1059 console.log(JSON.stringify(contentBlock.annotations, null, 2));1060 }1061 }1062 }1063 }10641065### Java10661067 import com.google.genai.Client;1068 import com.google.genai.gaos.models.interactions.Content;1069 import com.google.genai.gaos.models.interactions.CreateModelInteraction;1070 import com.google.genai.gaos.models.interactions.FileSearch;1071 import com.google.genai.gaos.models.interactions.Interaction;1072 import com.google.genai.gaos.models.interactions.InteractionsInput;1073 import com.google.genai.gaos.models.interactions.Model;1074 import com.google.genai.gaos.models.interactions.ModelOutputStep;1075 import com.google.genai.gaos.models.interactions.Step;1076 import com.google.genai.gaos.models.interactions.TextContent;1077 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;1078 import java.util.Arrays;10791080 Client client = new Client();10811082 CreateModelInteraction params =1083 CreateModelInteraction.builder()1084 .model(Model.of("gemini-3.8-flash"))1085 .input(InteractionsInput.of("Can you tell me about [insert question]"))1086 .tools(1087 Arrays.asList(1088 FileSearch.builder()1089 .fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))1090 .build()))1091 .build();10921093 Interaction interaction =1094 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();10951096 if (interaction.steps().isPresent()) {1097 for (Step step : interaction.steps().get()) {1098 if (step instanceof ModelOutputStep) {1099 ModelOutputStep outputStep = (ModelOutputStep) step;1100 if (outputStep.content().isPresent()) {1101 for (Content content : outputStep.content().get()) {1102 if (content instanceof TextContent) {1103 TextContent textContent = (TextContent) content;1104 if (textContent.annotations().isPresent()) {1105 System.out.println(textContent.annotations().get());1106 }1107 }1108 }1109 }1110 }1111 }1112 }11131114### REST11151116 {1117 "steps": [1118 {1119 "type": "model_output",1120 "content": [1121 {1122 "type": "text",1123 "text": "...",1124 "annotations": [1125 {1126 "type": "file_citation",1127 "file_name": "sample.txt",1128 "source": "..."1129 }1130 ]1131 }1132 ]1133 }1134 ]1135 }11361137For detailed information on the structure of the citations, see the1138[API reference for Interactions](https://ai.google.dev/api/interactions-api#Resource:FileCitation).11391140### Page numbers11411142When you use File Search with documents that have pages (such as PDFs), the1143model's response may include the page number where the information was found.1144You can access this information through the `page_number` attribute of a1145`file_citation` annotation.11461147### Python11481149 for step in interaction.steps:1150 if step.type == "model_output":1151 for content in step.content:1152 if content.type == "text" and content.annotations:1153 for annotation in content.annotations:1154 if annotation.type == "file_citation" and annotation.page_number:1155 print(f"Cited Page: {annotation.page_number}")11561157### JavaScript11581159 for (const step of interaction.steps) {1160 if (step.type === 'model_output') {1161 for (const block of step.content) {1162 if (block.type === 'text' && block.annotations) {1163 for (const annotation of block.annotations) {1164 if (annotation.type === 'file_citation' && annotation.pageNumber) {1165 console.log(`Cited Page: ${annotation.pageNumber}`);1166 }1167 }1168 }1169 }1170 }1171 }11721173### Java11741175 import com.google.genai.Client;1176 import com.google.genai.gaos.models.interactions.Annotation;1177 import com.google.genai.gaos.models.interactions.Content;1178 import com.google.genai.gaos.models.interactions.CreateModelInteraction;1179 import com.google.genai.gaos.models.interactions.FileCitation;1180 import com.google.genai.gaos.models.interactions.FileSearch;1181 import com.google.genai.gaos.models.interactions.Interaction;1182 import com.google.genai.gaos.models.interactions.InteractionsInput;1183 import com.google.genai.gaos.models.interactions.Model;1184 import com.google.genai.gaos.models.interactions.ModelOutputStep;1185 import com.google.genai.gaos.models.interactions.Step;1186 import com.google.genai.gaos.models.interactions.TextContent;1187 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;1188 import java.util.Arrays;11891190 Client client = new Client();11911192 CreateModelInteraction params =1193 CreateModelInteraction.builder()1194 .model(Model.of("gemini-3.8-flash"))1195 .input(InteractionsInput.of("Can you tell me about [insert question]"))1196 .tools(1197 Arrays.asList(1198 FileSearch.builder()1199 .fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))1200 .build()))1201 .build();12021203 Interaction interaction =1204 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();12051206 if (interaction.steps().isPresent()) {1207 for (Step step : interaction.steps().get()) {1208 if (step instanceof ModelOutputStep) {1209 ModelOutputStep outputStep = (ModelOutputStep) step;1210 if (outputStep.content().isPresent()) {1211 for (Content content : outputStep.content().get()) {1212 if (content instanceof TextContent) {1213 TextContent textContent = (TextContent) content;1214 if (textContent.annotations().isPresent()) {1215 for (Annotation annotation : textContent.annotations().get()) {1216 if (annotation instanceof FileCitation) {1217 FileCitation citation = (FileCitation) annotation;1218 if (citation.pageNumber().isPresent()) {1219 System.out.println("Cited Page: " + citation.pageNumber().get());1220 }1221 }1222 }1223 }1224 }1225 }1226 }1227 }1228 }1229 }12301231### REST12321233 {1234 "steps": [1235 {1236 "type": "model_output",1237 "content": [1238 {1239 "type": "text",1240 "text": "...",1241 "annotations": [1242 {1243 "type": "file_citation",1244 "file_name": "document.pdf",1245 "page_number": 1,1246 "source": "..."1247 }1248 ]1249 }1250 ]1251 }1252 ]1253 }12541255### Media citations12561257When the model references an image chunk during generation, the API returns an1258annotation of type `file_citation` in the annotations that includes a `media_id`. You can use this1259ID to download the exact image chunk the model referenced. This `media_id` is1260persistent across multiple search calls, which lets you reliably retrieve1261the same image or cache it using the ID.12621263The following snippet is an example REST response step:12641265 {1266 "type": "model_output",1267 "content": [1268 {1269 "type": "text",1270 "text": "...",1271 "annotations": [1272 {1273 "type": "file_citation",1274 "file_name": "product_image",1275 "media_id": "fileSearchStores/my-store-123/media/BlobId-456"1276 }1277 ]1278 }1279 ]1280 }12811282The following code snippets demonstrate how to retrieve the `media_id` and1283download the media:12841285### Python12861287 for step in interaction.steps:1288 if step.type == "model_output":1289 for content in step.content:1290 if content.type == "text" and content.annotations:1291 for annotation in content.annotations:1292 if annotation.type == "file_citation" and annotation.media_id:1293 print(f"Cited Media ID: {annotation.media_id}")1294 blob_content = client.file_search_stores.download_media(1295 media_id=annotation.media_id1296 )12971298### JavaScript12991300 for (const step of interaction.steps) {1301 if (step.type === 'model_output') {1302 for (const block of step.content) {1303 if (block.type === 'text' && block.annotations) {1304 for (const annotation of block.annotations) {1305 if (annotation.type === 'file_citation' && annotation.mediaId) {1306 console.log(`Cited Media ID: ${annotation.mediaId}`);1307 const blobContent = await ai.fileSearchStores.downloadMedia(annotation.mediaId);1308 }1309 }1310 }1311 }1312 }1313 }13141315### Java13161317 import com.google.genai.Client;1318 import com.google.genai.gaos.models.interactions.Annotation;1319 import com.google.genai.gaos.models.interactions.Content;1320 import com.google.genai.gaos.models.interactions.CreateModelInteraction;1321 import com.google.genai.gaos.models.interactions.FileCitation;1322 import com.google.genai.gaos.models.interactions.FileSearch;1323 import com.google.genai.gaos.models.interactions.Interaction;1324 import com.google.genai.gaos.models.interactions.InteractionsInput;1325 import com.google.genai.gaos.models.interactions.Model;1326 import com.google.genai.gaos.models.interactions.ModelOutputStep;1327 import com.google.genai.gaos.models.interactions.Step;1328 import com.google.genai.gaos.models.interactions.TextContent;1329 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;1330 import java.util.Arrays;13311332 Client client = new Client();13331334 CreateModelInteraction params =1335 CreateModelInteraction.builder()1336 .model(Model.of("gemini-3.8-flash"))1337 .input(InteractionsInput.of("Can you tell me about [insert question]"))1338 .tools(1339 Arrays.asList(1340 FileSearch.builder()1341 .fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))1342 .build()))1343 .build();13441345 Interaction interaction =1346 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();13471348 if (interaction.steps().isPresent()) {1349 for (Step step : interaction.steps().get()) {1350 if (step instanceof ModelOutputStep) {1351 ModelOutputStep outputStep = (ModelOutputStep) step;1352 if (outputStep.content().isPresent()) {1353 for (Content content : outputStep.content().get()) {1354 if (content instanceof TextContent) {1355 TextContent textContent = (TextContent) content;1356 if (textContent.annotations().isPresent()) {1357 for (Annotation annotation : textContent.annotations().get()) {1358 if (annotation instanceof FileCitation) {1359 FileCitation citation = (FileCitation) annotation;1360 if (citation.mediaId().isPresent()) {1361 System.out.println("Cited Media ID: " + citation.mediaId().get());1362 byte[] blobContent =1363 client.fileSearchStores.downloadMedia(citation.mediaId().get(), null);1364 }1365 }1366 }1367 }1368 }1369 }1370 }1371 }1372 }1373 }13741375### REST13761377 curl -X GET "https://generativelanguage.googleapis.com/v1/fileSearchStores/my-store-123/media/BlobId-456" \1378 -H "x-goog-api-key: $GEMINI_API_KEY"13791380## Custom metadata13811382If you have added custom metadata to your files, you can access it in the1383annotations of the model's response. This is useful for passing1384additional context (like URLs, page numbers, or authors) from your source1385documents to your application logic. Each citation annotation of type `file_citation`1386contains this custom metadata.13871388### Python13891390 interaction = client.interactions.create(1391 model="gemini-3.8-flash",1392 input="Tell me about [insert question]",1393 tools=[{1394 "type": "file_search",1395 "file_search_store_names": [file_search_store.name]1396 }]1397 )13981399 for step in interaction.steps:1400 if step.type == "model_output":1401 for content_block in step.content:1402 if content_block.annotations:1403 for annotation in content_block.annotations:1404 print(annotation)14051406### JavaScript14071408 const interaction = await ai.interactions.create({1409 model: "gemini-3.8-flash",1410 input: "Tell me about [insert question]",1411 tools: [{1412 type: "file_search",1413 file_search_store_names: [fileSearchStore.name]1414 }]1415 });14161417 for (const step of interaction.steps) {1418 if (step.type === 'model_output') {1419 for (const contentBlock of step.content) {1420 if (contentBlock.annotations) {1421 contentBlock.annotations.forEach((annotation) => {1422 console.log(annotation);1423 });1424 }1425 }1426 }1427 }14281429### Java14301431 import com.google.genai.Client;1432 import com.google.genai.gaos.models.interactions.Annotation;1433 import com.google.genai.gaos.models.interactions.Content;1434 import com.google.genai.gaos.models.interactions.CreateModelInteraction;1435 import com.google.genai.gaos.models.interactions.FileSearch;1436 import com.google.genai.gaos.models.interactions.Interaction;1437 import com.google.genai.gaos.models.interactions.InteractionsInput;1438 import com.google.genai.gaos.models.interactions.Model;1439 import com.google.genai.gaos.models.interactions.ModelOutputStep;1440 import com.google.genai.gaos.models.interactions.Step;1441 import com.google.genai.gaos.models.interactions.TextContent;1442 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;1443 import java.util.Arrays;14441445 Client client = new Client();14461447 CreateModelInteraction params =1448 CreateModelInteraction.builder()1449 .model(Model.of("gemini-3.8-flash"))1450 .input(InteractionsInput.of("Tell me about [insert question]"))1451 .tools(1452 Arrays.asList(1453 FileSearch.builder()1454 .fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))1455 .build()))1456 .build();14571458 Interaction interaction =1459 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();14601461 if (interaction.steps().isPresent()) {1462 for (Step step : interaction.steps().get()) {1463 if (step instanceof ModelOutputStep) {1464 ModelOutputStep outputStep = (ModelOutputStep) step;1465 if (outputStep.content().isPresent()) {1466 for (Content contentBlock : outputStep.content().get()) {1467 if (contentBlock instanceof TextContent) {1468 TextContent textContent = (TextContent) contentBlock;1469 if (textContent.annotations().isPresent()) {1470 for (Annotation annotation : textContent.annotations().get()) {1471 System.out.println(annotation);1472 }1473 }1474 }1475 }1476 }1477 }1478 }1479 }14801481### REST14821483 {1484 "steps": [1485 {1486 "type": "model_output",1487 "content": [1488 {1489 "type": "text",1490 "text": "...",1491 "annotations": [1492 {1493 "file_name": "...",1494 "source": "...",1495 "custom_metadata": [1496 {1497 "key": "author",1498 "string_value": "Robert Graves"1499 },1500 {1501 "key": "year",1502 "numeric_value": 19341503 }1504 ]1505 }1506 ]1507 }1508 ]1509 }1510 ]1511 }15121513## Structured output15141515Starting with Gemini 3 models, you can combine file search tool with1516[structured outputs](https://ai.google.dev/gemini-api/docs/structured-output).15171518### Python15191520 from pydantic import BaseModel, Field15211522 class Money(BaseModel):1523 amount: str = Field(description="The numerical part of the amount.")1524 currency: str = Field(description="The currency of amount.")15251526 interaction = client.interactions.create(1527 model="gemini-3.8-flash",1528 input="What is the minimum hourly wage in Tokyo right now?",1529 tools=[{1530 "type": "file_search",1531 "file_search_store_names": [file_search_store.name]1532 }],1533 response_format={1534 "type": "text",1535 "mime_type": "application/json",1536 "schema": Money.model_json_schema()1537 },1538 )1539 result = Money.model_validate_json(interaction.output_text)1540 print(result)15411542### JavaScript15431544 import { z } from "zod";15451546 const moneyJsonSchema = {1547 type: "object",1548 properties: {1549 amount: { type: "string", description: "The numerical part of the amount." },1550 currency: { type: "string", description: "The currency of amount." }1551 },1552 required: ["amount", "currency"]1553 };15541555 const moneySchema = z.fromJSONSchema(moneyJsonSchema);15561557 async function run() {1558 const interaction = await ai.interactions.create({1559 model: "gemini-3.8-flash",1560 input: "What is the minimum hourly wage in Tokyo right now?",1561 tools: [{1562 type: "file_search",1563 file_search_store_names: [fileSearchStore.name],1564 }],1565 response_format: {1566 type: 'text',1567 mime_type: 'application/json',1568 schema: moneyJsonSchema1569 },1570 });15711572 const result = moneySchema.parse(JSON.parse(interaction.output_text));1573 console.log(result);1574 }15751576 run();15771578### Java15791580 import com.google.genai.Client;1581 import com.google.genai.gaos.models.interactions.CreateModelInteraction;1582 import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat;1583 import com.google.genai.gaos.models.interactions.FileSearch;1584 import com.google.genai.gaos.models.interactions.Interaction;1585 import com.google.genai.gaos.models.interactions.InteractionsInput;1586 import com.google.genai.gaos.models.interactions.Model;1587 import com.google.genai.gaos.models.interactions.ResponseFormat;1588 import com.google.genai.gaos.models.interactions.TextResponseFormat;1589 import com.google.genai.gaos.models.interactions.TextResponseFormatMimeType;1590 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;1591 import java.util.Arrays;1592 import java.util.HashMap;1593 import java.util.Map;15941595 Client client = new Client();15961597 Map<String, Object> properties = new HashMap<>();15981599 Map<String, Object> amountProp = new HashMap<>();1600 amountProp.put("type", "string");1601 amountProp.put("description", "The numerical part of the amount.");1602 properties.put("amount", amountProp);16031604 Map<String, Object> currencyProp = new HashMap<>();1605 currencyProp.put("type", "string");1606 currencyProp.put("description", "The currency of amount.");1607 properties.put("currency", currencyProp);16081609 Map<String, Object> moneyJsonSchema = new HashMap<>();1610 moneyJsonSchema.put("type", "object");1611 moneyJsonSchema.put("properties", properties);1612 moneyJsonSchema.put("required", Arrays.asList("amount", "currency"));16131614 CreateModelInteractionResponseFormat format =1615 CreateModelInteractionResponseFormat.of(1616 ResponseFormat.of(1617 TextResponseFormat.builder()1618 .mimeType(TextResponseFormatMimeType.APPLICATION_JSON)1619 .schema(moneyJsonSchema)1620 .build()));16211622 CreateModelInteraction params =1623 CreateModelInteraction.builder()1624 .model(Model.of("gemini-3.8-flash"))1625 .input(InteractionsInput.of("What is the minimum hourly wage in Tokyo right now?"))1626 .tools(1627 Arrays.asList(1628 FileSearch.builder()1629 .fileSearchStoreNames(Arrays.asList("fileSearchStores/myfilesearchstore123"))1630 .build()))1631 .responseFormat(format)1632 .build();16331634 Interaction interaction =1635 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();16361637 System.out.println(interaction.outputText().orElse(""));16381639### REST16401641 curl "https://generativelanguage.googleapis.com/v1beta/interactions" \1642 -H "x-goog-api-key: $GEMINI_API_KEY" \1643 -H 'Content-Type: application/json' \1644 -X POST \1645 -d '{1646 "model": "gemini-3.8-flash",1647 "input": "What is the minimum hourly wage in Tokyo right now?",1648 "tools": [{1649 "type": "file_search",1650 "file_search_store_names": ["$FILE_SEARCH_STORE_NAME"]1651 }],1652 "response_format": {1653 "type": "text",1654 "mime_type": "application/json",1655 "schema": {1656 "type": "object",1657 "properties": {1658 "amount": {"type": "string", "description": "The numerical part of the amount."},1659 "currency": {"type": "string", "description": "The currency of amount."}1660 },1661 "required": ["amount", "currency"]1662 }1663 }1664 }'16651666## Supported models16671668The following models support File Search:16691670| Model | File Search |1671|---|---|1672| [Gemini 3.8 Flash](https://ai.google.dev/gemini-api/docs/models/gemini-3.8-flash) | ✔️ |1673| [Gemini 3.7 Flash](https://ai.google.dev/gemini-api/docs/models/gemini-3.7-flash) | ✔️ |1674| [Gemini 3.6 Flash](https://ai.google.dev/gemini-api/docs/models/gemini-3.6-flash) | ✔️ |1675| [Gemini 3.5 Flash-Lite](https://ai.google.dev/gemini-api/docs/models/gemini-3.5-flash-lite) | ✔️ |1676| [Gemini 3.5 Flash](https://ai.google.dev/gemini-api/docs/models/gemini-3.5-flash) | ✔️ |1677| [Gemini 3.1 Pro Preview](https://ai.google.dev/gemini-api/docs/models/gemini-3.1-pro-preview) | ✔️ |1678| [Gemini 3.1 Flash-Lite](https://ai.google.dev/gemini-api/docs/models/gemini-3.1-flash-lite) | ✔️ |1679| [Gemini 3 Flash Preview](https://ai.google.dev/gemini-api/docs/models/gemini-3-flash-preview) | ✔️ |16801681## Supported file types16821683File Search supports a wide range of file formats, listed in the following1684sections.16851686### Application file types16871688- `application/dart`1689- `application/ecmascript`1690- `application/json`1691- `application/ms-java`1692- `application/msword`1693- `application/pdf`1694- `application/sql`1695- `application/typescript`1696- `application/vnd.curl`1697- `application/vnd.dart`1698- `application/vnd.ibm.secure-container`1699- `application/vnd.jupyter`1700- `application/vnd.ms-excel`1701- `application/vnd.oasis.opendocument.text`1702- `application/vnd.openxmlformats-officedocument.presentationml.presentation`1703- `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`1704- `application/vnd.openxmlformats-officedocument.wordprocessingml.document`1705- `application/vnd.openxmlformats-officedocument.wordprocessingml.template`1706- `application/x-csh`1707- `application/x-hwp`1708- `application/x-hwp-v5`1709- `application/x-latex`1710- `application/x-php`1711- `application/x-powershell`1712- `application/x-sh`1713- `application/x-shellscript`1714- `application/x-tex`1715- `application/x-zsh`1716- `application/xml`1717- `application/zip`17181719### Text file types17201721- `text/1d-interleaved-parityfec`1722- `text/RED`1723- `text/SGML`1724- `text/cache-manifest`1725- `text/calendar`1726- `text/cql`1727- `text/cql-extension`1728- `text/cql-identifier`1729- `text/css`1730- `text/csv`1731- `text/csv-schema`1732- `text/dns`1733- `text/encaprtp`1734- `text/enriched`1735- `text/example`1736- `text/fhirpath`1737- `text/flexfec`1738- `text/fwdred`1739- `text/gff3`1740- `text/grammar-ref-list`1741- `text/hl7v2`1742- `text/html`1743- `text/javascript`1744- `text/jcr-cnd`1745- `text/jsx`1746- `text/markdown`1747- `text/mizar`1748- `text/n3`1749- `text/parameters`1750- `text/parityfec`1751- `text/php`1752- `text/plain`1753- `text/provenance-notation`1754- `text/prs.fallenstein.rst`1755- `text/prs.lines.tag`1756- `text/prs.prop.logic`1757- `text/raptorfec`1758- `text/rfc822-headers`1759- `text/rtf`1760- `text/rtp-enc-aescm128`1761- `text/rtploopback`1762- `text/rtx`1763- `text/sgml`1764- `text/shaclc`1765- `text/shex`1766- `text/spdx`1767- `text/strings`1768- `text/t140`1769- `text/tab-separated-values`1770- `text/texmacs`1771- `text/troff`1772- `text/tsv`1773- `text/tsx`1774- `text/turtle`1775- `text/ulpfec`1776- `text/uri-list`1777- `text/vcard`1778- `text/vnd.DMClientScript`1779- `text/vnd.IPTC.NITF`1780- `text/vnd.IPTC.NewsML`1781- `text/vnd.a`1782- `text/vnd.abc`1783- `text/vnd.ascii-art`1784- `text/vnd.curl`1785- `text/vnd.debian.copyright`1786- `text/vnd.dvb.subtitle`1787- `text/vnd.esmertec.theme-descriptor`1788- `text/vnd.exchangeable`1789- `text/vnd.familysearch.gedcom`1790- `text/vnd.ficlab.flt`1791- `text/vnd.fly`1792- `text/vnd.fmi.flexstor`1793- `text/vnd.gml`1794- `text/vnd.graphviz`1795- `text/vnd.hans`1796- `text/vnd.hgl`1797- `text/vnd.in3d.3dml`1798- `text/vnd.in3d.spot`1799- `text/vnd.latex-z`1800- `text/vnd.motorola.reflex`1801- `text/vnd.ms-mediapackage`1802- `text/vnd.net2phone.commcenter.command`1803- `text/vnd.radisys.msml-basic-layout`1804- `text/vnd.senx.warpscript`1805- `text/vnd.sosi`1806- `text/vnd.sun.j2me.app-descriptor`1807- `text/vnd.trolltech.linguist`1808- `text/vnd.wap.si`1809- `text/vnd.wap.sl`1810- `text/vnd.wap.wml`1811- `text/vnd.wap.wmlscript`1812- `text/vtt`1813- `text/wgsl`1814- `text/x-asm`1815- `text/x-bibtex`1816- `text/x-boo`1817- `text/x-c`1818- `text/x-c++hdr`1819- `text/x-c++src`1820- `text/x-cassandra`1821- `text/x-chdr`1822- `text/x-coffeescript`1823- `text/x-component`1824- `text/x-csh`1825- `text/x-csharp`1826- `text/x-csrc`1827- `text/x-cuda`1828- `text/x-d`1829- `text/x-diff`1830- `text/x-dsrc`1831- `text/x-emacs-lisp`1832- `text/x-erlang`1833- `text/x-gff3`1834- `text/x-go`1835- `text/x-haskell`1836- `text/x-java`1837- `text/x-java-properties`1838- `text/x-java-source`1839- `text/x-kotlin`1840- `text/x-lilypond`1841- `text/x-lisp`1842- `text/x-literate-haskell`1843- `text/x-lua`1844- `text/x-moc`1845- `text/x-objcsrc`1846- `text/x-pascal`1847- `text/x-pcs-gcd`1848- `text/x-perl`1849- `text/x-perl-script`1850- `text/x-python`1851- `text/x-python-script`1852- `text/x-r-markdown`1853- `text/x-rsrc`1854- `text/x-rst`1855- `text/x-ruby-script`1856- `text/x-rust`1857- `text/x-sass`1858- `text/x-scala`1859- `text/x-scheme`1860- `text/x-script.python`1861- `text/x-scss`1862- `text/x-setext`1863- `text/x-sfv`1864- `text/x-sh`1865- `text/x-siesta`1866- `text/x-sos`1867- `text/x-sql`1868- `text/x-swift`1869- `text/x-tcl`1870- `text/x-tex`1871- `text/x-vbasic`1872- `text/x-vcalendar`1873- `text/xml`1874- `text/xml-dtd`1875- `text/xml-external-parsed-entity`1876- `text/yaml`18771878## Limitations18791880- **Live API:** File Search is not supported in the [Live API](https://ai.google.dev/gemini-api/docs/live).1881- **Tool incompatibility:** Built-in grounding tools cannot be combined with one another; for example, File Search cannot be used simultaneously with [Grounding with Google Search](https://ai.google.dev/gemini-api/docs/google-search) or [URL Context](https://ai.google.dev/gemini-api/docs/url-context) in the same request.18821883### Rate limits18841885The File Search API has the following limits to enforce service stability:18861887- **Maximum file size / per document limit**: 100 MB1888- **Total size of project File Search stores** (based on user tier):1889 - **Free**: 1 GB1890 - **Tier 1**: 10 GB1891 - **Tier 2**: 100 GB1892 - **Tier 3**: 1 TB1893- **Recommendation**: Limit the size of each File Search store to under 20 GB to ensure optimal retrieval latencies.18941895> [!NOTE]1896> **Note:** The limit on File Search store size is computed on the backend, based on the size of your input plus the embeddings generated and stored with it. This is typically approximately 3 times the size of your input data.18971898## Pricing18991900- You are charged for embeddings at indexing time based on existing [embeddings pricing](https://ai.google.dev/gemini-api/docs/pricing#gemini-embedding-2).1901- Storage is free of charge.1902- Query time embeddings are free of charge.1903- Retrieved document tokens are charged as regular [context tokens](https://ai.google.dev/gemini-api/docs/tokens).19041905## What's next19061907- Visit the API reference for [File Search Stores](https://ai.google.dev/api/file-search/file-search-stores) and File Search [Documents](https://ai.google.dev/api/file-search/documents).