SPB Git

Repository Public

document-processing.md 22.7 KB 699 lines markdown

1# Document understanding23> [!NOTE]4> **Note** : This version of the page covers the new [Interactions API](https://ai.google.dev/gemini-api/docs/interactions/interactions-overview), which is currently in Beta.  5> For stable production deployments, we recommend you continue to use the `generateContent` API. You can use the toggle on this page to switch between the versions.67Gemini models can process documents in PDF format, using native8vision to understand entire document contexts. This goes beyond9just text extraction, allowing Gemini to:1011- Analyze and interpret content, including text, images, diagrams, charts, and tables, even in long documents up to 1000 pages.12- Extract information into [structured output](https://ai.google.dev/gemini-api/docs/interactions/structured-output) formats.13- Summarize and answer questions based on both the visual and textual elements in a document.14- Transcribe document content (e.g. to HTML), preserving layouts and formatting, for use in downstream applications.1516You can also pass non-PDF documents in the same way but Gemini will see them17as normal text which will eliminate context like charts or formatting.1819## Passing PDF data inline2021You can pass PDF data inline in the request. This is best22suited for smaller documents or temporary processing where you don't need to23reference the file in subsequent requests. We recommend using the24[Files API](https://ai.google.dev/gemini-api/docs/interactions/document-processing#large-pdfs)25for larger documents that you need to refer to in multi-turn interactions to26improve request latency and reduce bandwidth usage.2728The following example shows you how to pass PDF data inline:2930### Python3132    from google import genai33    import base643435    client = genai.Client()3637    with open('path/to/document.pdf', 'rb') as f:38        pdf_bytes = f.read()3940    interaction = client.interactions.create(41        model="gemini-3.5-flash",42        input=[43            {44                "type": "document",45                "data": base64.b64encode(pdf_bytes).decode('utf-8'),46                "mime_type": "application/pdf"47            },48            {"type": "text", "text": "Summarize this document"}49        ]50    )5152    print(interaction.output_text)5354### JavaScript5556    import { GoogleGenAI } from "@google/genai";57    import * as fs from "node:fs";5859    const ai = new GoogleGenAI({});6061    async function main() {62        const pdfData = fs.readFileSync("path/to/document.pdf", {63            encoding: "base64"64        });6566        const interaction = await ai.interactions.create({67            model: "gemini-3.5-flash",68            input: [69                { type: "text", text: "Summarize this document" },70                {71                    type: "document",72                    data: pdfData,73                    mime_type: "application/pdf"74                }75            ]76        });77        console.log(interaction.output_text);78    }7980    main();8182### REST8384    PDF_PATH="path/to/document.pdf"8586    if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then87      B64FLAGS="--input"88    else89      B64FLAGS="-w0"90    fi9192    curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \93      -H "x-goog-api-key: $GEMINI_API_KEY" \94      -H 'Content-Type: application/json' \95      -H "Api-Revision: 2026-05-20" \96      -d '{97        "model": "gemini-3.5-flash",98        "input": [99          {100            "type": "document",101            "data": "'$(base64 $B64FLAGS $PDF_PATH)'",102            "mime_type": "application/pdf"103          },104          {"type": "text", "text": "Summarize this document"}105        ]106      }'107108You can also upload a local PDF file for processing:109110### Python111112    from google import genai113114    client = genai.Client()115116    uploaded_file = client.files.upload(file="file.pdf")117118    interaction = client.interactions.create(119        model="gemini-3.5-flash",120        input=[121            {"type": "document", "uri": uploaded_file.uri, "mime_type": uploaded_file.mime_type},122            {"type": "text", "text": "Summarize this document"}123        ]124    )125    print(interaction.output_text)126127### JavaScript128129    import { GoogleGenAI } from "@google/genai";130131    const ai = new GoogleGenAI({});132133    async function main() {134        const uploadedFile = await ai.files.upload({135            file: "file.pdf",136            config: { mime_type: "application/pdf" }137        });138139        const interaction = await ai.interactions.create({140            model: "gemini-3.5-flash",141            input: [142                { type: "text", text: "Summarize this document" },143                {144                    type: "document",145                    uri: uploadedFile.uri,146                    mime_type: uploadedFile.mime_type147                }148            ]149        });150        console.log(interaction.output_text);151    }152153    main();154155## Uploading PDFs using the Files API156157We recommend you use Files API for larger files or when you intend to reuse a158document across multiple requests. This improves request latency and reduces159bandwidth usage by decoupling the file upload from the model requests.160161> [!NOTE]162> **Note:** The Files API is available at no cost in all regions where the Gemini API is available. Uploaded files are stored for 48 hours.163164### Large PDFs from URLs165166Use the File API to simplify uploading and processing large PDF files from URLs:167168### Python169170    from google import genai171    import io172    import httpx173174    client = genai.Client()175176    long_context_pdf_path = "https://arxiv.org/pdf/2312.11805"177178    doc_io = io.BytesIO(httpx.get(long_context_pdf_path).content)179180    sample_doc = client.files.upload(181      file=doc_io,182      config=dict(183        mime_type='application/pdf')184    )185186    prompt = "Summarize this document"187188    interaction = client.interactions.create(189        model="gemini-3.5-flash",190        input=[191            {"type": "document", "uri": sample_doc.uri, "mime_type": sample_doc.mime_type},192            {"type": "text", "text": prompt}193        ]194    )195    print(interaction.output_text)196197### JavaScript198199    import { GoogleGenAI } from "@google/genai";200201    const ai = new GoogleGenAI({});202203    async function main() {204205        const pdfBuffer = await fetch("https://arxiv.org/pdf/2312.11805")206            .then((response) => response.arrayBuffer());207208        const fileBlob = new Blob([pdfBuffer], { type: 'application/pdf' });209210        const file = await ai.files.upload({211            file: fileBlob,212            config: {213                displayName: 'A17_FlightPlan.pdf',214            },215        });216217        let getFile = await ai.files.get({ name: file.name });218        while (getFile.state === 'PROCESSING') {219            getFile = await ai.files.get({ name: file.name });220            console.log(`current file status: ${getFile.state}`);221            console.log('File is still processing, retrying in 5 seconds');222223            await new Promise((resolve) => {224                setTimeout(resolve, 5000);225            });226        }227        if (file.state === 'FAILED') {228            throw new Error('File processing failed.');229        }230231        const interaction = await ai.interactions.create({232            model: 'gemini-3.5-flash',233            input: [234                { type: "document", uri: file.uri, mime_type: file.mime_type },235                { type: "text", text: "Summarize this document" }236            ],237        });238239        console.log(interaction.output_text);240241    }242243    main();244245### REST246247    PDF_PATH="https://arxiv.org/pdf/2312.11805"248    DISPLAY_NAME="Gemini_paper"249    PROMPT="Summarize this document"250251    # Download the PDF from the provided URL252    wget -O "${DISPLAY_NAME}.pdf" "${PDF_PATH}"253254    MIME_TYPE=$(file -b --mime-type "${DISPLAY_NAME}.pdf")255    NUM_BYTES=$(wc -c < "${DISPLAY_NAME}.pdf")256257    echo "MIME_TYPE: ${MIME_TYPE}"258    echo "NUM_BYTES: ${NUM_BYTES}"259260    tmp_header_file=upload-header.tmp261262    # Initial resumable request defining metadata.263    # The upload url is in the response headers dump them to a file.264    curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GEMINI_API_KEY}" \265      -D upload-header.tmp \266      -H "X-Goog-Upload-Protocol: resumable" \267      -H "X-Goog-Upload-Command: start" \268      -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \269      -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \270      -H "Content-Type: application/json" \271      -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null272273    upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")274    rm "${tmp_header_file}"275276    # Upload the actual bytes.277    curl "${upload_url}" \278      -H "Content-Length: ${NUM_BYTES}" \279      -H "X-Goog-Upload-Offset: 0" \280      -H "X-Goog-Upload-Command: upload, finalize" \281      --data-binary "@${DISPLAY_NAME}.pdf" 2> /dev/null > file_info.json282283    file_uri=$(jq -r ".file.uri" file_info.json)284    echo "file_uri: ${file_uri}"285286    # Create payload JSON file for safety287    cat << EOF > payload.json288    {289      "model": "gemini-3.5-flash",290      "input": [291        {"type": "text", "text": "${PROMPT}"},292        {"type": "document", "uri": "${file_uri}", "mime_type": "application/pdf"}293      ]294    }295    EOF296297    # Now create an interaction using that file298    curl "https://generativelanguage.googleapis.com/v1beta/interactions" \299        -H "x-goog-api-key: $GEMINI_API_KEY" \300        -H 'Content-Type: application/json' \301        -H "Api-Revision: 2026-05-20" \302        -X POST \303        -d @payload.json 2> /dev/null > response.json304305    cat response.json306    echo307308    jq ".steps[-1].content[0].text" response.json309310    # Clean up311    rm "${DISPLAY_NAME}.pdf"312    rm payload.json313314### Large PDFs stored locally315316### Python317318    from google import genai319    import pathlib320321    client = genai.Client()322323    file_path = pathlib.Path('large_file.pdf')324    sample_file = client.files.upload(325        file=file_path,326    )327328    interaction = client.interactions.create(329        model="gemini-3.5-flash",330        input=[331            {"type": "document", "uri": sample_file.uri, "mime_type": sample_file.mime_type},332            {"type": "text", "text": "Summarize this document"}333        ]334    )335    print(interaction.output_text)336337### JavaScript338339    import { GoogleGenAI } from "@google/genai";340341    const ai = new GoogleGenAI({});342343    async function main() {344        const file = await ai.files.upload({345            file: 'path-to-localfile.pdf',346            config: {347                displayName: 'A17_FlightPlan.pdf',348            },349        });350351        let getFile = await ai.files.get({ name: file.name });352        while (getFile.state === 'PROCESSING') {353            getFile = await ai.files.get({ name: file.name });354            console.log(`current file status: ${getFile.state}`);355            console.log('File is still processing, retrying in 5 seconds');356357            await new Promise((resolve) => {358                setTimeout(resolve, 5000);359            });360        }361        if (file.state === 'FAILED') {362            throw new Error('File processing failed.');363        }364365        const interaction = await ai.interactions.create({366            model: 'gemini-3.5-flash',367            input: [368                { type: "document", uri: file.uri, mime_type: file.mime_type },369                { type: "text", text: "Summarize this document" }370            ],371        });372373        console.log(interaction.output_text);374375    }376377    main();378379### REST380381    PDF_PATH="path/to/large_file.pdf"382    NUM_BYTES=$(wc -c < "${PDF_PATH}")383    DISPLAY_NAME=TEXT384    tmp_header_file=upload-header.tmp385386    # Initial resumable request defining metadata.387    # The upload url is in the response headers dump them to a file.388    curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GEMINI_API_KEY}" \389      -D upload-header.tmp \390      -H "X-Goog-Upload-Protocol: resumable" \391      -H "X-Goog-Upload-Command: start" \392      -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \393      -H "X-Goog-Upload-Header-Content-Type: application/pdf" \394      -H "Content-Type: application/json" \395      -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null396397    upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")398    rm "${tmp_header_file}"399400    # Upload the actual bytes.401    curl "${upload_url}" \402      -H "Content-Length: ${NUM_BYTES}" \403      -H "X-Goog-Upload-Offset: 0" \404      -H "X-Goog-Upload-Command: upload, finalize" \405      --data-binary "@${PDF_PATH}" 2> /dev/null > file_info.json406407    file_uri=$(jq ".file.uri" file_info.json)408    echo file_uri=$file_uri409410    # Now create an interaction using that file411    curl "https://generativelanguage.googleapis.com/v1beta/interactions" \412        -H "x-goog-api-key: $GEMINI_API_KEY" \413        -H 'Content-Type: application/json' \414        -H "Api-Revision: 2026-05-20" \415        -X POST \416        -d '{417          "model": "gemini-3.5-flash",418          "input": [419            {"type": "document", "uri": '$file_uri', "mime_type": "application/pdf"},420            {"type": "text", "text": "Can you add a few more lines to this poem?"}421          ]422        }' 2> /dev/null > response.json423424    cat response.json425    echo426427    jq ".steps[-1].content[0].text" response.json428429You can verify the API successfully stored the uploaded file and get its430metadata by calling [`files.get`](https://ai.google.dev/api/rest/v1beta/files/get). Only the `name`431(and by extension, the `uri`) are unique.432433### Python434435    from google import genai436    import pathlib437438    client = genai.Client()439440    fpath = pathlib.Path('example.pdf')441    fpath.write_text('hello')442443    file = client.files.upload(file='example.pdf')444445    file_info = client.files.get(name=file.name)446    print(file_info.model_dump_json(indent=4))447448### REST449450    name=$(jq -r ".file.name" file_info.json)451    # Get the file of interest to check state452    curl "https://generativelanguage.googleapis.com/v1beta/$name?key=$GEMINI_API_KEY" > file_info.json453    # Print some information about the file you got454    name=$(jq -r ".name" file_info.json)455    echo name=$name456    file_uri=$(jq -r ".uri" file_info.json)457    echo file_uri=$file_uri458459## Passing multiple PDFs460461The Gemini API is capable of processing multiple PDF documents (up to 1000 pages)462in a single request, as long as the combined size of the documents and the text463prompt stays within the model's context window.464465### Python466467    from google import genai468    import io469    import httpx470471    client = genai.Client()472473    doc_url_1 = "https://arxiv.org/pdf/2312.11805"474    doc_url_2 = "https://arxiv.org/pdf/2403.05530"475476    doc_data_1 = io.BytesIO(httpx.get(doc_url_1).content)477    doc_data_2 = io.BytesIO(httpx.get(doc_url_2).content)478479    sample_pdf_1 = client.files.upload(480      file=doc_data_1,481      config=dict(mime_type='application/pdf')482    )483    sample_pdf_2 = client.files.upload(484      file=doc_data_2,485      config=dict(mime_type='application/pdf')486    )487488    prompt = "What is the difference between each of the main benchmarks between these two papers? Output these in a table."489490    interaction = client.interactions.create(491        model="gemini-3.5-flash",492        input=[493            {"type": "document", "uri": sample_pdf_1.uri, "mime_type": sample_pdf_1.mime_type},494            {"type": "document", "uri": sample_pdf_2.uri, "mime_type": sample_pdf_2.mime_type},495            {"type": "text", "text": prompt}496        ]497    )498499    print(interaction.output_text)500501### JavaScript502503    import { GoogleGenAI } from "@google/genai";504505    const ai = new GoogleGenAI({});506507    async function uploadRemotePDF(url, displayName) {508        const pdfBuffer = await fetch(url)509            .then((response) => response.arrayBuffer());510511        const fileBlob = new Blob([pdfBuffer], { type: 'application/pdf' });512513        const file = await ai.files.upload({514            file: fileBlob,515            config: {516                displayName: displayName,517            },518        });519520        let getFile = await ai.files.get({ name: file.name });521        while (getFile.state === 'PROCESSING') {522            getFile = await ai.files.get({ name: file.name });523            console.log(`current file status: ${getFile.state}`);524            console.log('File is still processing, retrying in 5 seconds');525526            await new Promise((resolve) => {527                setTimeout(resolve, 5000);528            });529        }530        if (file.state === 'FAILED') {531            throw new Error('File processing failed.');532        }533534        return file;535    }536537    async function main() {538        const file1 = await uploadRemotePDF("https://arxiv.org/pdf/2312.11805", "PDF 1");539        const file2 = await uploadRemotePDF("https://arxiv.org/pdf/2403.05530", "PDF 2");540541        const interaction = await ai.interactions.create({542            model: 'gemini-3.5-flash',543            input: [544                { type: "document", uri: file1.uri, mime_type: file1.mime_type },545                { type: "document", uri: file2.uri, mime_type: file2.mime_type },546                { type: "text", text: "What is the difference between each of the main benchmarks between these two papers? Output these in a table." }547            ],548        });549550        console.log(interaction.output_text);551    }552553    main();554555### REST556557    DOC_URL_1="https://arxiv.org/pdf/2312.11805"558    DOC_URL_2="https://arxiv.org/pdf/2403.05530"559    DISPLAY_NAME_1="Gemini_paper"560    DISPLAY_NAME_2="Gemini_1.5_paper"561    PROMPT="What is the difference between each of the main benchmarks between these two papers? Output these in a table."562563    # Function to download and upload a PDF564    upload_pdf() {565      local doc_url="$1"566      local display_name="$2"567568      echo "Downloading ${display_name} from ${doc_url}..." >&2569      # Download the PDF570      wget -O "${display_name}.pdf" "${doc_url}" 2> /dev/null571572      local MIME_TYPE=$(file -b --mime-type "${display_name}.pdf")573      local NUM_BYTES=$(wc -c < "${display_name}.pdf")574575      echo "MIME_TYPE: ${MIME_TYPE}" >&2576      echo "NUM_BYTES: ${NUM_BYTES}" >&2577578      local tmp_header_file="upload-header-${display_name}.tmp"579580      # Initial resumable request581      # Using GEMINI_API_KEY instead of GOOGLE_API_KEY582      curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GEMINI_API_KEY}" \583        -D "${tmp_header_file}" \584        -H "X-Goog-Upload-Protocol: resumable" \585        -H "X-Goog-Upload-Command: start" \586        -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \587        -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \588        -H "Content-Type: application/json" \589        -d "{'file': {'display_name': '${display_name}'}}" 2> /dev/null590591      local upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")592      rm "${tmp_header_file}"593594      echo "Upload URL for ${display_name}: ${upload_url}" >&2595596      # Upload the PDF597      curl "${upload_url}" \598        -H "Content-Length: ${NUM_BYTES}" \599        -H "X-Goog-Upload-Offset: 0" \600        -H "X-Goog-Upload-Command: upload, finalize" \601        --data-binary "@${display_name}.pdf" 2> /dev/null > "file_info_${display_name}.json"602603      local file_uri=$(jq -r ".file.uri" "file_info_${display_name}.json")604      echo "file_uri for ${display_name}: ${file_uri}" >&2605606      # Clean up the downloaded PDF607      rm "${display_name}.pdf"608609      echo "${file_uri}"610    }611612    # Upload the first PDF613    file_uri_1=$(upload_pdf "${DOC_URL_1}" "${DISPLAY_NAME_1}")614615    # Upload the second PDF616    file_uri_2=$(upload_pdf "${DOC_URL_2}" "${DISPLAY_NAME_2}")617618    # Create payload JSON file for safety619    cat << EOF > payload_multi.json620    {621      "model": "gemini-3.5-flash",622      "input": [623        {"type": "document", "uri": "${file_uri_1}", "mime_type": "application/pdf"},624        {"type": "document", "uri": "${file_uri_2}", "mime_type": "application/pdf"},625        {"type": "text", "text": "${PROMPT}"}626      ]627    }628    EOF629630    # Now create an interaction using both files631    # Using GEMINI_API_KEY instead of GOOGLE_API_KEY632    curl "https://generativelanguage.googleapis.com/v1beta/interactions" \633        -H "x-goog-api-key: $GEMINI_API_KEY" \634        -H 'Content-Type: application/json' \635        -H "Api-Revision: 2026-05-20" \636        -X POST \637        -d @payload_multi.json 2> /dev/null > response.json638639    cat response.json640    echo641642    jq ".steps[-1].content[0].text" response.json643644    # Clean up645    rm payload_multi.json646    rm "file_info_${DISPLAY_NAME_1}.json"647    rm "file_info_${DISPLAY_NAME_2}.json"648649## Technical details650651Gemini supports PDF files up to 50MB or 1000 pages. This limit applies652to both inline data and Files API uploads. Each document page is equivalent to 258653tokens.654655While there are no specific limits to the number of pixels in a document besides656the model's [context window](https://ai.google.dev/gemini-api/docs/long-context), larger pages are657scaled down to a maximum resolution of 3072 x 3072 while preserving their original658aspect ratio, while smaller pages are scaled up to 768 x 768 pixels. There is no659cost reduction for pages at lower sizes, other than bandwidth, or performance660improvement for pages at higher resolution.661662### Gemini 3 models663664Gemini 3 introduces granular control over multimodal vision processing with the665`media_resolution` parameter. You can now set the resolution to low, medium, or666high per individual media part. With this addition, the processing of PDF667documents has been updated:6686691. **Native text inclusion:** Text natively embedded in the PDF is extracted and provided to the model.6702. **Billing \& token reporting:**671   - You are **not charged** for tokens originating from the extracted **native text** in PDFs.672   - In the `usage_metadata` section of the API response, tokens generated from processing PDF pages (as images) are now counted under the `IMAGE` modality, not a separate `DOCUMENT` modality as in some earlier versions.673674### Document types675676Technically, you can pass other MIME types for document understanding, like677TXT, Markdown, HTML, XML, etc. However, document vision ***only meaningfully678understands PDFs***. Other types will be extracted as pure text, and the model679won't be able to interpret what we see in the rendering of those files. Any680file-type specifics like charts, diagrams, HTML tags, Markdown formatting, etc.,681will be lost.682683To learn about other file input methods, see the684[File input methods](https://ai.google.dev/gemini-api/docs/interactions/file-input-methods) guide.685686### Best practices687688For best results:689690- Rotate pages to the correct orientation before uploading.691- Avoid blurry pages.692- If using a single page, place the text prompt after the page.693694## What's next695696To learn more, see the following resources:697698- [File prompting strategies](https://ai.google.dev/gemini-api/docs/interactions/files#prompt-guide): The Gemini API supports prompting with text, image, audio, and video data, also known as multimodal prompting.699- [System instructions](https://ai.google.dev/gemini-api/docs/interactions/text-generation#system-instructions): System instructions let you steer the behavior of the model based on your specific needs and use cases.
Files main
Menu

Theme