Files API Guide
View SourceThe Files API allows you to upload, manage, and use files with Gemini models for multimodal content generation.
Overview
Files uploaded to the Gemini API can be:
- Used in content generation requests (images, audio, video, documents)
- Referenced by URI in multimodal prompts
- Managed with list, get, and delete operations
Important Notes:
- Files expire after 48 hours
- Maximum file size is 2GB for most file types
- Large files (especially video) may take time to process
Quick Start
# Upload an image
{:ok, file} = Gemini.APIs.Files.upload("path/to/image.png")
# Wait for processing (for video files)
{:ok, ready_file} = Gemini.APIs.Files.wait_for_processing(file.name)
# Use in content generation
{:ok, response} = Gemini.generate([
"What's in this image?",
%{file_uri: ready_file.uri, mime_type: ready_file.mime_type}
])
# Clean up when done
:ok = Gemini.APIs.Files.delete(file.name)Uploading Files
From File Path
# Simple upload
{:ok, file} = Gemini.APIs.Files.upload("document.pdf")
# With options
{:ok, file} = Gemini.APIs.Files.upload("video.mp4",
display_name: "My Video",
mime_type: "video/mp4"
)From Binary Data
When you have file content in memory:
image_data = File.read!("image.png")
{:ok, file} = Gemini.APIs.Files.upload_data(image_data,
mime_type: "image/png",
display_name: "In-Memory Image"
)With Progress Tracking
For large files, track upload progress:
{:ok, file} = Gemini.APIs.Files.upload("large_video.mp4",
on_progress: fn uploaded, total ->
percent = Float.round(uploaded / total * 100, 1)
IO.puts("Uploaded: #{percent}%")
end
)File States
After upload, files go through processing states:
| State | Description |
|---|---|
:processing | File is being processed |
:active | Ready for use |
:failed | Processing failed |
Waiting for Processing
For video and large files that need processing:
{:ok, file} = Gemini.APIs.Files.upload("video.mp4")
# Wait with default settings (5 min timeout)
{:ok, ready} = Gemini.APIs.Files.wait_for_processing(file.name)
# Or with custom options
{:ok, ready} = Gemini.APIs.Files.wait_for_processing(file.name,
poll_interval: 5000, # Check every 5 seconds
timeout: 600_000, # 10 minute timeout
on_status: fn f -> IO.puts("State: #{f.state}") end
)Listing Files
List with Pagination
{:ok, response} = Gemini.APIs.Files.list()
Enum.each(response.files, fn file ->
IO.puts("#{file.name}: #{file.mime_type} (#{file.state})")
end)
# With pagination options
{:ok, response} = Gemini.APIs.Files.list(page_size: 10)
if Gemini.Types.ListFilesResponse.has_more_pages?(response) do
{:ok, page2} = Gemini.APIs.Files.list(page_token: response.next_page_token)
endList All Files
Automatically handles pagination:
{:ok, all_files} = Gemini.APIs.Files.list_all()
IO.puts("Total files: #{length(all_files)}")
# Filter active files
active = Enum.filter(all_files, &Gemini.Types.File.active?/1)Getting File Metadata
{:ok, file} = Gemini.APIs.Files.get("files/abc123")
IO.puts("Name: #{file.display_name}")
IO.puts("MIME type: #{file.mime_type}")
IO.puts("Size: #{file.size_bytes} bytes")
IO.puts("State: #{file.state}")
IO.puts("URI: #{file.uri}")Deleting Files
:ok = Gemini.APIs.Files.delete("files/abc123")Using Files in Generation
Once a file is active, use it in content generation:
{:ok, file} = Gemini.APIs.Files.upload("photo.jpg")
{:ok, ready} = Gemini.APIs.Files.wait_for_processing(file.name)
{:ok, response} = Gemini.generate([
"Describe this image in detail",
%{file_uri: ready.uri, mime_type: ready.mime_type}
])Supported MIME Types
Images
image/png,image/jpeg,image/gif,image/webp,image/heic,image/heif
Videos
video/mp4,video/mpeg,video/mov,video/avi,video/webm,video/wmv,video/flv,video/mkv
Audio
audio/wav,audio/mp3,audio/aiff,audio/aac,audio/ogg,audio/flac,audio/m4a
Documents
application/pdf,text/plain,text/html,text/css,text/javascript,application/json,text/csv,text/markdown
File Helper Functions
alias Gemini.Types.File
# Check file state
File.active?(file) # Ready for use?
File.processing?(file) # Still processing?
File.failed?(file) # Processing failed?
# Get file ID from name
File.get_id(file) # "abc123" from "files/abc123"
# Check if downloadable (for generated files)
File.downloadable?(file)Error Handling
case Gemini.APIs.Files.upload("file.pdf") do
{:ok, file} ->
IO.puts("Uploaded: #{file.name}")
{:error, {:file_not_found, path}} ->
IO.puts("File not found: #{path}")
{:error, {:http_error, status, body}} ->
IO.puts("HTTP error #{status}: #{inspect(body)}")
{:error, reason} ->
IO.puts("Upload failed: #{inspect(reason)}")
endBest Practices
- Clean up files - Delete files when no longer needed to avoid hitting storage limits
- Wait for processing - Always wait for video/audio files to become active before using
- Track progress - Use
on_progresscallback for large file uploads - Handle expiration - Files expire after 48 hours; re-upload if needed
- Use appropriate MIME types - Let auto-detection work, or specify explicitly
API Reference
Gemini.APIs.Files.upload/2- Upload a file from pathGemini.APIs.Files.upload_data/2- Upload binary dataGemini.APIs.Files.get/2- Get file metadataGemini.APIs.Files.list/1- List files with paginationGemini.APIs.Files.list_all/1- List all filesGemini.APIs.Files.delete/2- Delete a fileGemini.APIs.Files.wait_for_processing/2- Wait for file to become activeGemini.APIs.Files.download/2- Download generated file content