Skip to content
Blog

Gemini File Input Methods: Inline Data, File API, GCS, and URLs Compared

Compare the four ways to include media files in Gemini Interactions API requests - inline base64 data, File API upload, GCS URI registration, and external URLs - with size limits, persistence, and code examples for each.

Published on August 5, 2026

AI Assistant

Introduction

When you build with the Gemini API, one of the first decisions you face is: how do I get my files into the request? Whether you’re working with images, audio, video, or documents, the method you choose depends on the size of your file, where your data is stored, and how frequently you plan to use it.

The Gemini API supports four file input methods, all of which work with every endpoint, including Batch, Interactions, and Live:

  1. Inline data — base64-encoded bytes sent directly in the request.
  2. File API upload — upload and store files on Google’s servers.
  3. GCS URI registration — register files already in Google Cloud Storage.
  4. External / signed URLs — point the API at a publicly hosted URL.

In this post we’ll compare these methods, show you how to use each one, and help you pick the right approach for your use case.

Input method comparison

MethodBest forMax file sizePersistence
Inline dataQuick testing, small files, real-time applications.100 MB per request or payload (50 MB for PDFs)None (sent with every request)
File API uploadLarge files, files used multiple times.2 GB per file, up to 20 GB per project48 Hours
GCS URI registrationLarge files already in Google Cloud Storage, files used multiple times.2 GB per file, no overall storage limitsNone (fetched per request). One-time registration can give access up to 30 days.
External URLsPublic data or data in cloud buckets (AWS, Azure, GCS) without re-uploading.100 MB per request/payloadNone (fetched per request)

Reading a local file inline

The simplest way to include a file is to read it locally and include it inline in a prompt. Here’s an example reading a local PDF (PDFs are limited to 50 MB for this method).

Python

from google import genai
import pathlib
import base64

client = genai.Client()

filepath = pathlib.Path('my_local_file.pdf')

prompt = "Summarize this document"
interaction = client.interactions.create(
    model="gemini-3.6-flash",
    input=[
        {"type": "text", "text": prompt},
        {"type": "document", "data": base64.b64encode(filepath.read_bytes()).decode('utf-8'), "mime_type": "application/pdf"}
    ]
)
print(interaction.output_text)

JavaScript

import { GoogleGenAI } from "@google/genai";
import * as fs from 'node:fs';

const client = new GoogleGenAI({});
const prompt = "Summarize this document";

async function main() {
    const filePath = 'my_local_file.pdf';

    const interaction = await client.interactions.create({
        model: "gemini-3.6-flash",
        input: [
            { type: "text", text: prompt },
            {
                type: "document",
                data: fs.readFileSync(filePath).toString("base64"),
                mime_type: "application/pdf"
            }
        ]
    });
    console.log(interaction.output_text);
}

main();

REST

# Encode the local file to base64
B64_CONTENT=$(base64 -w 0 my_local_file.pdf)

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gemini-3.6-flash",
    "input": [
      {"type": "text", "text": "Summarize this document"},
      {
        "type": "document",
        "data": "'${B64_CONTENT}'",
        "mime_type": "application/pdf"
      }
    ]
  }'

Inline data

For smaller files (under 100 MB, or 50 MB for PDFs), you can pass data directly in the request payload. This is the simplest method for quick tests or applications handling real-time, transient data. You can supply data as base64-encoded strings or by reading local files directly. Just remember: inline data is sent with every request — it doesn’t persist anywhere.

Fetching inline data from a URL

You can also fetch a file from a URL, convert it to bytes, and include it inline.

Python

from google import genai
import base64
import httpx

client = genai.Client()

doc_url = "https://discovery.ucl.ac.uk/id/eprint/10089234/1/343019_3_art_0_py4t4l_convrt.pdf"
doc_data = httpx.get(doc_url).content

prompt = "Summarize this document"

interaction = client.interactions.create(
    model="gemini-3.6-flash",
    input=[
        {"type": "document", "data": base64.b64encode(doc_data).decode('utf-8'), "mime_type": "application/pdf"},
        {"type": "text", "text": prompt}
    ]
)
print(interaction.output_text)

JavaScript

import { GoogleGenAI } from "@google/genai";

const client = new GoogleGenAI({});
const docUrl = 'https://discovery.ucl.ac.uk/id/eprint/10089234/1/343019_3_art_0_py4t4l_convrt.pdf';
const prompt = "Summarize this document";

async function main() {
    const pdfResp = await fetch(docUrl)
      .then((response) => response.arrayBuffer());

    const interaction = await client.interactions.create({
        model: "gemini-3.6-flash",
        input: [
            { type: "text", text: prompt },
            {
                type: "document",
                data: Buffer.from(pdfResp).toString("base64"),
                mime_type: "application/pdf"
            }
        ]
    });
    console.log(interaction.output_text);
}

main();

Gemini File API upload

The File API is designed for larger files (up to 2 GB) or files you intend to use in multiple requests. Files uploaded this way are stored temporarily (48 hours) and processed for efficient retrieval by the model.

Standard file upload

Python

from google import genai

client = genai.Client()

doc_file = client.files.upload(file="path/to/your/sample.pdf")
prompt = "Summarize this document"

interaction = client.interactions.create(
    model="gemini-3.6-flash",
    input=[
        {"type": "text", "text": prompt},
        {"type": "document", "uri": doc_file.uri, "mime_type": doc_file.mime_type}
    ]
)
print(interaction.output_text)

JavaScript

import { GoogleGenAI } from "@google/genai";

const client = new GoogleGenAI({});
const prompt = "Summarize this document";

async function main() {
  const filePath = "path/to/your/sample.pdf";

  const myfile = await client.files.upload({
    file: filePath,
    config: { mime_type: "application/pdf" },
  });

  const interaction = await client.interactions.create({
    model: "gemini-3.6-flash",
    input: [
        { type: "text", text: prompt },
        { type: "document", uri: myfile.uri, mime_type: myfile.mimeType }
    ]
  });
  console.log(interaction.output_text);
}

await main();

Registering Google Cloud Storage files

If your data is already in Google Cloud Storage, you don’t need to download and re-upload it. You can register it directly with the File API. Registration gives access for up to 30 days, and there are no storage limits — it’s fetched per request.

The setup involves three steps:

  1. Grant Service Agent access to each bucket:

    • Enable the Gemini API in your Google Cloud project.
    • Create the Service Agent: gcloud beta services identity create --service=generativelanguage.googleapis.com --project=<your_project>
    • Assign the Storage Object Viewer IAM role to this service agent on the buckets you intend to use. This access doesn’t expire by default.
  2. Authenticate your service with Storage Object Viewer permissions. If you’re running outside Google Cloud, download a service account key and use Credentials.from_service_account_file (Python) or GoogleAuth with a key file (JavaScript). If you’re running inside Google Cloud (Cloud Run, Compute Engine), use Application Default Credentials instead.

  3. Register the files with the Files API to produce paths usable in the Gemini API:

Python (registering)

from google import genai

client = genai.Client(credentials=credentials)

registered_gcs_files = client.files.register_files(
    uris=["gs://my_bucket/some_object.pdf", "gs://bucket2/object2.txt"]
)
prompt = "Summarize this file."

for f in registered_gcs_files.files:
  print(f.name)
  interaction = client.interactions.create(
    model="gemini-3.6-flash",
    input=[
      {"type": "text", "text": prompt},
      {"type": "document", "uri": f.uri, "mime_type": f.mime_type}
    ],
  )
  print(interaction.output_text)

JavaScript (registering)

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({ auth: auth });

async function main() {
    const registeredGcsFiles = await ai.files.registerFiles({
        uris: ["gs://my_bucket/some_object.pdf", "gs://bucket2/object2.txt"]
    });

    const prompt = "Summarize this file.";

    for (const file of registeredGcsFiles.files) {
        console.log(file.name);
        const interaction = await ai.interactions.create({
            model: "gemini-3.6-flash",
            input: [
                { type: "text", text: prompt },
                { type: "document", uri: file.uri, mime_type: file.mimeType }
            ]
        });

        console.log(interaction.output_text);
    }
}

main();

External HTTP / signed URLs

You can pass publicly accessible HTTPS URLs or pre-signed URLs directly in your request. The Gemini API fetches the content securely during processing. This is ideal for files up to 100 MB that you don’t want to re-upload.

Note: Gemini 2.0 family models are not supported for this method.

Python

from google import genai

uri = "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
prompt = "Summarize this file"

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.6-flash",
    input=[
        {"type": "document", "uri": uri, "mime_type": "application/pdf"},
        {"type": "text", "text": prompt}
    ]
)
print(interaction.output_text)

JavaScript

import { GoogleGenAI } from '@google/genai';

const client = new GoogleGenAI({});

const uri = "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf";

async function main() {
  const interaction = await client.interactions.create({
    model: 'gemini-3.6-flash',
    input: [
      { type: "document", uri: uri, mime_type: "application/pdf" },
      { type: "text", text: "summarize this file" }
    ]
  });

  console.log(interaction.output_text);
}

main();

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
      -H 'x-goog-api-key: $GEMINI_API_KEY' \
      -H 'Content-Type: application/json' \
      -d '{
          "model": "gemini-3.6-flash",
          "input": [
            {"type": "text", "text": "Summarize this pdf"},
            {
              "type": "document",
              "uri": "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf",
              "mime_type": "application/pdf"
            }
          ]
        }'

Accessibility and safety

  • Accessibility: Verify URLs don’t lead to pages requiring a login or sitting behind a paywall. For private databases, create a signed URL with the correct permissions and expiry.
  • Safety checks: The system performs content moderation on the URL. If the URL fails the check, you’ll get a url_retrieval_status of URL_RETRIEVAL_STATUS_UNSAFE.

Supported content types for URLs

Content retrieval for external URLs only supports publicly accessible URLs, and only for these types:

Text: text/html, text/css, text/plain, text/xml, text/csv, text/rtf, text/javascript

Application: application/json, application/pdf

Image: image/bmp, image/jpeg, image/png, image/webp

Video: video/mp4, video/mpeg, video/quicktime, video/avi, video/x-flv, video/mpg, video/webm, video/wmv, video/3gpp

Best practices

  • Choose the right method: Use inline data for small, transient files. Use the File API for larger or frequently used files. Use external URLs for data already hosted online.
  • Specify MIME types: Always provide the correct MIME type so the file is processed properly.
  • Handle errors: Implement error handling for network failures, file access problems, and API errors.

Limitations to keep in mind

  • File size limits vary by method and file type.
  • Inline data increases request payload size.
  • File API uploads are temporary and expire after 48 hours.
  • External URL fetching is limited to 100 MB per payload and supports specific content types.

Summary

You now have a complete toolkit for feeding files into the Gemini API. Reach for inline data for quick, small, transient files; the File API for large or frequently reused files; GCS registration when your data already lives in Google Cloud Storage; and external URLs when your content is already hosted online. Match the method to your data’s size, location, and usage pattern, and your multimodal applications will be both faster and more reliable.

Further reading