Repository Public
1Gemini models can process documents in PDF format, using native2vision to understand entire document contexts. This goes beyond3just text extraction, allowing Gemini to:45- Analyze and interpret content, including text, images, diagrams, charts, and tables, even in long documents up to 1000 pages.6- Extract information into [structured output](https://ai.google.dev/gemini-api/docs/structured-output) formats.7- Summarize and answer questions based on both the visual and textual elements in a document.8- Transcribe document content (e.g. to HTML), preserving layouts and formatting, for use in downstream applications.910You can also pass non-PDF documents in the same way but Gemini will see them11as normal text which will eliminate context like charts or formatting.1213## Passing PDF data inline1415You can pass PDF data inline in the request. This is best16suited for smaller documents or temporary processing where you don't need to17reference the file in subsequent requests. We recommend using the18[Files API](https://ai.google.dev/gemini-api/docs/document-processing#large-pdfs)19for larger documents that you need to refer to in multi-turn interactions to20improve request latency and reduce bandwidth usage.2122The following example shows you how to pass PDF data inline:2324### Python2526 from google import genai27 import base642829 client = genai.Client()3031 with open('path/to/document.pdf', 'rb') as f:32 pdf_bytes = f.read()3334 interaction = client.interactions.create(35 model="gemini-3.8-flash",36 input=[37 {38 "type": "document",39 "data": base64.b64encode(pdf_bytes).decode('utf-8'),40 "mime_type": "application/pdf"41 },42 {"type": "text", "text": "Summarize this document"}43 ]44 )4546 print(interaction.output_text)4748### JavaScript4950 import { GoogleGenAI } from "@google/genai";51 import * as fs from "node:fs";5253 const ai = new GoogleGenAI({});5455 async function main() {56 const pdfData = fs.readFileSync("path/to/document.pdf", {57 encoding: "base64"58 });5960 const interaction = await ai.interactions.create({61 model: "gemini-3.8-flash",62 input: [63 { type: "text", text: "Summarize this document" },64 {65 type: "document",66 data: pdfData,67 mime_type: "application/pdf"68 }69 ]70 });71 console.log(interaction.output_text);72 }7374 main();7576### Java7778 import com.google.genai.Client;79 import com.google.genai.gaos.models.interactions.Content;80 import com.google.genai.gaos.models.interactions.CreateModelInteraction;81 import com.google.genai.gaos.models.interactions.DocumentContent;82 import com.google.genai.gaos.models.interactions.DocumentContentMimeType;83 import com.google.genai.gaos.models.interactions.Interaction;84 import com.google.genai.gaos.models.interactions.InteractionsInput;85 import com.google.genai.gaos.models.interactions.Model;86 import com.google.genai.gaos.models.interactions.TextContent;87 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;88 import java.nio.file.Files;89 import java.nio.file.Paths;90 import java.util.Arrays;91 import java.util.Base64;92 import java.util.List;9394 Client client = new Client();9596 byte[] pdfBytes = Files.readAllBytes(Paths.get("path/to/document.pdf"));97 String base64Pdf = Base64.getEncoder().encodeToString(pdfBytes);9899 Content docContent =100 DocumentContent.builder()101 .data(base64Pdf)102 .mimeType(DocumentContentMimeType.APPLICATION_PDF)103 .build();104 Content textContent = TextContent.builder().text("Summarize this document").build();105106 List<Content> contents = Arrays.asList(docContent, textContent);107108 CreateModelInteraction params =109 CreateModelInteraction.builder()110 .model(Model.of("gemini-3.8-flash"))111 .input(InteractionsInput.ofContent(contents))112 .build();113114 Interaction interaction =115 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();116 System.out.println(interaction.outputText().orElse(""));117118### REST119120 PDF_PATH="path/to/document.pdf"121122 if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then123 B64FLAGS="--input"124 else125 B64FLAGS="-w0"126 fi127128 curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \129 -H "x-goog-api-key: $GEMINI_API_KEY" \130 -H 'Content-Type: application/json' \131 -d '{132 "model": "gemini-3.8-flash",133 "input": [134 {135 "type": "document",136 "data": "'$(base64 $B64FLAGS $PDF_PATH)'",137 "mime_type": "application/pdf"138 },139 {"type": "text", "text": "Summarize this document"}140 ]141 }'142143You can also upload a local PDF file for processing:144145### Python146147 from google import genai148149 client = genai.Client()150151 uploaded_file = client.files.upload(file="file.pdf")152153 interaction = client.interactions.create(154 model="gemini-3.8-flash",155 input=[156 {"type": "document", "uri": uploaded_file.uri, "mime_type": uploaded_file.mime_type},157 {"type": "text", "text": "Summarize this document"}158 ]159 )160 print(interaction.output_text)161162### JavaScript163164 import { GoogleGenAI } from "@google/genai";165166 const ai = new GoogleGenAI({});167168 async function main() {169 const uploadedFile = await ai.files.upload({170 file: "file.pdf",171 config: { mime_type: "application/pdf" }172 });173174 const interaction = await ai.interactions.create({175 model: "gemini-3.8-flash",176 input: [177 { type: "text", text: "Summarize this document" },178 {179 type: "document",180 uri: uploadedFile.uri,181 mime_type: uploadedFile.mime_type182 }183 ]184 });185 console.log(interaction.output_text);186 }187188 main();189190### Java191192 import com.google.genai.Client;193 import com.google.genai.gaos.models.interactions.Content;194 import com.google.genai.gaos.models.interactions.CreateModelInteraction;195 import com.google.genai.gaos.models.interactions.DocumentContent;196 import com.google.genai.gaos.models.interactions.DocumentContentMimeType;197 import com.google.genai.gaos.models.interactions.Interaction;198 import com.google.genai.gaos.models.interactions.InteractionsInput;199 import com.google.genai.gaos.models.interactions.Model;200 import com.google.genai.gaos.models.interactions.TextContent;201 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;202 import com.google.genai.types.File;203 import com.google.genai.types.UploadFileConfig;204 import java.util.Arrays;205 import java.util.List;206207 Client client = new Client();208209 File uploadedFile =210 client.files.upload(211 new java.io.File("file.pdf"),212 UploadFileConfig.builder().mimeType("application/pdf").build());213214 Content docContent =215 DocumentContent.builder()216 .uri(uploadedFile.uri().orElse(""))217 .mimeType(DocumentContentMimeType.of(uploadedFile.mimeType().orElse("application/pdf")))218 .build();219 Content textContent = TextContent.builder().text("Summarize this document").build();220221 List<Content> contents = Arrays.asList(docContent, textContent);222223 CreateModelInteraction params =224 CreateModelInteraction.builder()225 .model(Model.of("gemini-3.8-flash"))226 .input(InteractionsInput.ofContent(contents))227 .build();228229 Interaction interaction =230 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();231 System.out.println(interaction.outputText().orElse(""));232233### REST234235 PDF_PATH="file.pdf"236 NUM_BYTES=$(wc -c < "${PDF_PATH}")237 DISPLAY_NAME="file.pdf"238 tmp_header_file=upload-header.tmp239240 # Initial resumable request defining metadata.241 # The upload url is in the response headers dump them to a file.242 curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GEMINI_API_KEY}" \243 -D upload-header.tmp \244 -H "X-Goog-Upload-Protocol: resumable" \245 -H "X-Goog-Upload-Command: start" \246 -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \247 -H "X-Goog-Upload-Header-Content-Type: application/pdf" \248 -H "Content-Type: application/json" \249 -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null250251 upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")252 rm "${tmp_header_file}"253254 # Upload the actual bytes.255 curl "${upload_url}" \256 -H "Content-Length: ${NUM_BYTES}" \257 -H "X-Goog-Upload-Offset: 0" \258 -H "X-Goog-Upload-Command: upload, finalize" \259 --data-binary "@${PDF_PATH}" 2> /dev/null > file_info.json260261 file_uri=$(jq -r ".file.uri" file_info.json)262 echo file_uri=$file_uri263264 # Now create an interaction using that file265 curl "https://generativelanguage.googleapis.com/v1beta/interactions" \266 -H "x-goog-api-key: $GEMINI_API_KEY" \267 -H 'Content-Type: application/json' \268 -X POST \269 -d '{270 "model": "gemini-3.8-flash",271 "input": [272 {"type": "document", "uri": "'$file_uri'", "mime_type": "application/pdf"},273 {"type": "text", "text": "Summarize this document"}274 ]275 }' 2> /dev/null > response.json276277 cat response.json278 echo279280 jq -r ".steps[-1].content[0].text" response.json281282## Uploading PDFs using the Files API283284We recommend you use Files API for larger files or when you intend to reuse a285document across multiple requests. This improves request latency and reduces286bandwidth usage by decoupling the file upload from the model requests.287288> [!NOTE]289> **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.290291### Large PDFs from URLs292293Use the File API to simplify uploading and processing large PDF files from URLs:294295### Python296297 from google import genai298 import io299 import httpx300301 client = genai.Client()302303 long_context_pdf_path = "https://arxiv.org/pdf/2312.11805"304305 doc_io = io.BytesIO(httpx.get(long_context_pdf_path).content)306307 sample_doc = client.files.upload(308 file=doc_io,309 config=dict(310 mime_type='application/pdf')311 )312313 prompt = "Summarize this document"314315 interaction = client.interactions.create(316 model="gemini-3.8-flash",317 input=[318 {"type": "document", "uri": sample_doc.uri, "mime_type": sample_doc.mime_type},319 {"type": "text", "text": prompt}320 ]321 )322 print(interaction.output_text)323324### JavaScript325326 import { GoogleGenAI } from "@google/genai";327328 const ai = new GoogleGenAI({});329330 async function main() {331332 const pdfBuffer = await fetch("https://arxiv.org/pdf/2312.11805")333 .then((response) => response.arrayBuffer());334335 const fileBlob = new Blob([pdfBuffer], { type: 'application/pdf' });336337 const file = await ai.files.upload({338 file: fileBlob,339 config: {340 displayName: 'A17_FlightPlan.pdf',341 },342 });343344 let getFile = await ai.files.get({ name: file.name });345 while (getFile.state === 'PROCESSING') {346 getFile = await ai.files.get({ name: file.name });347 console.log(`current file status: ${getFile.state}`);348 console.log('File is still processing, retrying in 5 seconds');349350 await new Promise((resolve) => {351 setTimeout(resolve, 5000);352 });353 }354 if (file.state === 'FAILED') {355 throw new Error('File processing failed.');356 }357358 const interaction = await ai.interactions.create({359 model: 'gemini-3.8-flash',360 input: [361 { type: "document", uri: file.uri, mime_type: file.mime_type },362 { type: "text", text: "Summarize this document" }363 ],364 });365366 console.log(interaction.output_text);367368 }369370 main();371372### Java373374 import com.google.genai.Client;375 import com.google.genai.gaos.models.interactions.Content;376 import com.google.genai.gaos.models.interactions.CreateModelInteraction;377 import com.google.genai.gaos.models.interactions.DocumentContent;378 import com.google.genai.gaos.models.interactions.DocumentContentMimeType;379 import com.google.genai.gaos.models.interactions.Interaction;380 import com.google.genai.gaos.models.interactions.InteractionsInput;381 import com.google.genai.gaos.models.interactions.Model;382 import com.google.genai.gaos.models.interactions.TextContent;383 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;384 import com.google.genai.types.File;385 import com.google.genai.types.UploadFileConfig;386 import java.net.URI;387 import java.net.http.HttpClient;388 import java.net.http.HttpRequest;389 import java.net.http.HttpResponse;390 import java.util.Arrays;391 import java.util.List;392393 Client client = new Client();394395 String longContextPdfPath = "https://arxiv.org/pdf/2312.11805";396 HttpClient httpClient = HttpClient.newHttpClient();397 HttpRequest request = HttpRequest.newBuilder().uri(URI.create(longContextPdfPath)).build();398 byte[] pdfBytes = httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray()).body();399400 File sampleDoc =401 client.files.upload(402 pdfBytes, UploadFileConfig.builder().mimeType("application/pdf").build());403404 String prompt = "Summarize this document";405406 Content docContent =407 DocumentContent.builder()408 .uri(sampleDoc.uri().orElse(""))409 .mimeType(DocumentContentMimeType.of(sampleDoc.mimeType().orElse("application/pdf")))410 .build();411 Content textContent = TextContent.builder().text(prompt).build();412413 List<Content> contents = Arrays.asList(docContent, textContent);414415 CreateModelInteraction params =416 CreateModelInteraction.builder()417 .model(Model.of("gemini-3.8-flash"))418 .input(InteractionsInput.ofContent(contents))419 .build();420421 Interaction interaction =422 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();423 System.out.println(interaction.outputText().orElse(""));424425### REST426427 PDF_PATH="https://arxiv.org/pdf/2312.11805"428 DISPLAY_NAME="Gemini_paper"429 PROMPT="Summarize this document"430431 # Download the PDF from the provided URL432 wget -O "${DISPLAY_NAME}.pdf" "${PDF_PATH}"433434 MIME_TYPE=$(file -b --mime-type "${DISPLAY_NAME}.pdf")435 NUM_BYTES=$(wc -c < "${DISPLAY_NAME}.pdf")436437 echo "MIME_TYPE: ${MIME_TYPE}"438 echo "NUM_BYTES: ${NUM_BYTES}"439440 tmp_header_file=upload-header.tmp441442 # Initial resumable request defining metadata.443 # The upload url is in the response headers dump them to a file.444 curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GEMINI_API_KEY}" \445 -D upload-header.tmp \446 -H "X-Goog-Upload-Protocol: resumable" \447 -H "X-Goog-Upload-Command: start" \448 -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \449 -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \450 -H "Content-Type: application/json" \451 -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null452453 upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")454 rm "${tmp_header_file}"455456 # Upload the actual bytes.457 curl "${upload_url}" \458 -H "Content-Length: ${NUM_BYTES}" \459 -H "X-Goog-Upload-Offset: 0" \460 -H "X-Goog-Upload-Command: upload, finalize" \461 --data-binary "@${DISPLAY_NAME}.pdf" 2> /dev/null > file_info.json462463 file_uri=$(jq -r ".file.uri" file_info.json)464 echo "file_uri: ${file_uri}"465466 # Create payload JSON file for safety467 cat << EOF > payload.json468 {469 "model": "gemini-3.8-flash",470 "input": [471 {"type": "text", "text": "${PROMPT}"},472 {"type": "document", "uri": "${file_uri}", "mime_type": "application/pdf"}473 ]474 }475 EOF476477 # Now create an interaction using that file478 curl "https://generativelanguage.googleapis.com/v1beta/interactions" \479 -H "x-goog-api-key: $GEMINI_API_KEY" \480 -H 'Content-Type: application/json' \481 -X POST \482 -d @payload.json 2> /dev/null > response.json483484 cat response.json485 echo486487 jq ".steps[-1].content[0].text" response.json488489 # Clean up490 rm "${DISPLAY_NAME}.pdf"491 rm payload.json492493### Large PDFs stored locally494495### Python496497 from google import genai498 import pathlib499500 client = genai.Client()501502 file_path = pathlib.Path('large_file.pdf')503 sample_file = client.files.upload(504 file=file_path,505 )506507 interaction = client.interactions.create(508 model="gemini-3.8-flash",509 input=[510 {"type": "document", "uri": sample_file.uri, "mime_type": sample_file.mime_type},511 {"type": "text", "text": "Summarize this document"}512 ]513 )514 print(interaction.output_text)515516### JavaScript517518 import { GoogleGenAI } from "@google/genai";519520 const ai = new GoogleGenAI({});521522 async function main() {523 const file = await ai.files.upload({524 file: 'large_file.pdf',525 config: {526 displayName: 'A17_FlightPlan.pdf',527 },528 });529530 let getFile = await ai.files.get({ name: file.name });531 while (getFile.state === 'PROCESSING') {532 getFile = await ai.files.get({ name: file.name });533 console.log(`current file status: ${getFile.state}`);534 console.log('File is still processing, retrying in 5 seconds');535536 await new Promise((resolve) => {537 setTimeout(resolve, 5000);538 });539 }540 if (file.state === 'FAILED') {541 throw new Error('File processing failed.');542 }543544 const interaction = await ai.interactions.create({545 model: 'gemini-3.8-flash',546 input: [547 { type: "document", uri: file.uri, mime_type: file.mime_type },548 { type: "text", text: "Summarize this document" }549 ],550 });551552 console.log(interaction.output_text);553554 }555556 main();557558### Java559560 import com.google.genai.Client;561 import com.google.genai.gaos.models.interactions.Content;562 import com.google.genai.gaos.models.interactions.CreateModelInteraction;563 import com.google.genai.gaos.models.interactions.DocumentContent;564 import com.google.genai.gaos.models.interactions.DocumentContentMimeType;565 import com.google.genai.gaos.models.interactions.Interaction;566 import com.google.genai.gaos.models.interactions.InteractionsInput;567 import com.google.genai.gaos.models.interactions.Model;568 import com.google.genai.gaos.models.interactions.TextContent;569 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;570 import com.google.genai.types.File;571 import com.google.genai.types.UploadFileConfig;572 import java.util.Arrays;573 import java.util.List;574575 Client client = new Client();576577 File sampleFile =578 client.files.upload(579 new java.io.File("large_file.pdf"),580 UploadFileConfig.builder().mimeType("application/pdf").build());581582 Content docContent =583 DocumentContent.builder()584 .uri(sampleFile.uri().orElse(""))585 .mimeType(DocumentContentMimeType.of(sampleFile.mimeType().orElse("application/pdf")))586 .build();587 Content textContent = TextContent.builder().text("Summarize this document").build();588589 List<Content> contents = Arrays.asList(docContent, textContent);590591 CreateModelInteraction params =592 CreateModelInteraction.builder()593 .model(Model.of("gemini-3.8-flash"))594 .input(InteractionsInput.ofContent(contents))595 .build();596597 Interaction interaction =598 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();599 System.out.println(interaction.outputText().orElse(""));600601### REST602603 PDF_PATH="large_file.pdf"604 NUM_BYTES=$(wc -c < "${PDF_PATH}")605 DISPLAY_NAME=TEXT606 tmp_header_file=upload-header.tmp607608 # Initial resumable request defining metadata.609 # The upload url is in the response headers dump them to a file.610 curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GEMINI_API_KEY}" \611 -D upload-header.tmp \612 -H "X-Goog-Upload-Protocol: resumable" \613 -H "X-Goog-Upload-Command: start" \614 -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \615 -H "X-Goog-Upload-Header-Content-Type: application/pdf" \616 -H "Content-Type: application/json" \617 -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null618619 upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")620 rm "${tmp_header_file}"621622 # Upload the actual bytes.623 curl "${upload_url}" \624 -H "Content-Length: ${NUM_BYTES}" \625 -H "X-Goog-Upload-Offset: 0" \626 -H "X-Goog-Upload-Command: upload, finalize" \627 --data-binary "@${PDF_PATH}" 2> /dev/null > file_info.json628629 file_uri=$(jq -r ".file.uri" file_info.json)630 echo file_uri=$file_uri631632 # Now create an interaction using that file633 curl "https://generativelanguage.googleapis.com/v1beta/interactions" \634 -H "x-goog-api-key: $GEMINI_API_KEY" \635 -H 'Content-Type: application/json' \636 -X POST \637 -d '{638 "model": "gemini-3.8-flash",639 "input": [640 {"type": "document", "uri": "'$file_uri'", "mime_type": "application/pdf"},641 {"type": "text", "text": "Can you add a few more lines to this poem?"}642 ]643 }' 2> /dev/null > response.json644645 cat response.json646 echo647648 jq -r ".steps[-1].content[0].text" response.json649650You can verify the API successfully stored the uploaded file and get its651metadata by calling [`files.get`](https://ai.google.dev/api/rest/v1beta/files/get). Only the `name`652(and by extension, the `uri`) are unique.653654### Python655656 from google import genai657 import pathlib658659 client = genai.Client()660661 fpath = pathlib.Path('example.pdf')662 fpath.write_text('hello')663664 file = client.files.upload(file='example.pdf')665666 file_info = client.files.get(name=file.name)667 print(file_info.model_dump_json(indent=4))668669### JavaScript670671 import { GoogleGenAI } from "@google/genai";672 import * as fs from "node:fs";673674 const ai = new GoogleGenAI({});675676 async function main() {677 fs.writeFileSync("example.pdf", "hello");678679 const file = await ai.files.upload({680 file: "example.pdf",681 config: { mime_type: "application/pdf" }682 });683684 const fileInfo = await ai.files.get({ name: file.name });685 console.log(fileInfo);686 }687688 main();689690### Java691692 import com.google.genai.Client;693 import com.google.genai.types.File;694 import com.google.genai.types.UploadFileConfig;695 import java.nio.charset.StandardCharsets;696 import java.nio.file.Files;697 import java.nio.file.Path;698 import java.nio.file.Paths;699700 Client client = new Client();701702 Path fpath = Paths.get("example.pdf");703 Files.write(fpath, "hello".getBytes(StandardCharsets.UTF_8));704705 File file =706 client.files.upload(707 fpath.toFile(), UploadFileConfig.builder().mimeType("application/pdf").build());708709 File fileInfo = client.files.get(file.name().orElse(""), null);710 System.out.println(fileInfo.toJson());711712### REST713714 name=$(jq -r ".file.name" file_info.json)715 # Get the file of interest to check state716 curl "https://generativelanguage.googleapis.com/v1beta/$name?key=$GEMINI_API_KEY" > file_info.json717 # Print some information about the file you got718 name=$(jq -r ".name" file_info.json)719 echo name=$name720 file_uri=$(jq -r ".uri" file_info.json)721 echo file_uri=$file_uri722723## Passing multiple PDFs724725The Gemini API is capable of processing multiple PDF documents (up to 1000 pages)726in a single request, as long as the combined size of the documents and the text727prompt stays within the model's context window.728729### Python730731 from google import genai732 import io733 import httpx734735 client = genai.Client()736737 doc_url_1 = "https://arxiv.org/pdf/2312.11805"738 doc_url_2 = "https://arxiv.org/pdf/2403.05530"739740 doc_data_1 = io.BytesIO(httpx.get(doc_url_1).content)741 doc_data_2 = io.BytesIO(httpx.get(doc_url_2).content)742743 sample_pdf_1 = client.files.upload(744 file=doc_data_1,745 config=dict(mime_type='application/pdf')746 )747 sample_pdf_2 = client.files.upload(748 file=doc_data_2,749 config=dict(mime_type='application/pdf')750 )751752 prompt = "What is the difference between each of the main benchmarks between these two papers? Output these in a table."753754 interaction = client.interactions.create(755 model="gemini-3.8-flash",756 input=[757 {"type": "document", "uri": sample_pdf_1.uri, "mime_type": sample_pdf_1.mime_type},758 {"type": "document", "uri": sample_pdf_2.uri, "mime_type": sample_pdf_2.mime_type},759 {"type": "text", "text": prompt}760 ]761 )762763 print(interaction.output_text)764765### JavaScript766767 import { GoogleGenAI } from "@google/genai";768769 const ai = new GoogleGenAI({});770771 async function uploadRemotePDF(url, displayName) {772 const pdfBuffer = await fetch(url)773 .then((response) => response.arrayBuffer());774775 const fileBlob = new Blob([pdfBuffer], { type: 'application/pdf' });776777 const file = await ai.files.upload({778 file: fileBlob,779 config: {780 displayName: displayName,781 },782 });783784 let getFile = await ai.files.get({ name: file.name });785 while (getFile.state === 'PROCESSING') {786 getFile = await ai.files.get({ name: file.name });787 console.log(`current file status: ${getFile.state}`);788 console.log('File is still processing, retrying in 5 seconds');789790 await new Promise((resolve) => {791 setTimeout(resolve, 5000);792 });793 }794 if (file.state === 'FAILED') {795 throw new Error('File processing failed.');796 }797798 return file;799 }800801 async function main() {802 const file1 = await uploadRemotePDF("https://arxiv.org/pdf/2312.11805", "PDF 1");803 const file2 = await uploadRemotePDF("https://arxiv.org/pdf/2403.05530", "PDF 2");804805 const interaction = await ai.interactions.create({806 model: 'gemini-3.8-flash',807 input: [808 { type: "document", uri: file1.uri, mime_type: file1.mime_type },809 { type: "document", uri: file2.uri, mime_type: file2.mime_type },810 { type: "text", text: "What is the difference between each of the main benchmarks between these two papers? Output these in a table." }811 ],812 });813814 console.log(interaction.output_text);815 }816817 main();818819### Java820821 import com.google.genai.Client;822 import com.google.genai.gaos.models.interactions.Content;823 import com.google.genai.gaos.models.interactions.CreateModelInteraction;824 import com.google.genai.gaos.models.interactions.DocumentContent;825 import com.google.genai.gaos.models.interactions.DocumentContentMimeType;826 import com.google.genai.gaos.models.interactions.Interaction;827 import com.google.genai.gaos.models.interactions.InteractionsInput;828 import com.google.genai.gaos.models.interactions.Model;829 import com.google.genai.gaos.models.interactions.TextContent;830 import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;831 import com.google.genai.types.File;832 import com.google.genai.types.UploadFileConfig;833 import java.net.URI;834 import java.net.http.HttpClient;835 import java.net.http.HttpRequest;836 import java.net.http.HttpResponse;837 import java.util.Arrays;838 import java.util.List;839840 Client client = new Client();841842 String docUrl1 = "https://arxiv.org/pdf/2312.11805";843 String docUrl2 = "https://arxiv.org/pdf/2403.05530";844845 HttpClient httpClient = HttpClient.newHttpClient();846 byte[] docData1 =847 httpClient848 .send(HttpRequest.newBuilder().uri(URI.create(docUrl1)).build(), HttpResponse.BodyHandlers.ofByteArray())849 .body();850 byte[] docData2 =851 httpClient852 .send(HttpRequest.newBuilder().uri(URI.create(docUrl2)).build(), HttpResponse.BodyHandlers.ofByteArray())853 .body();854855 File samplePdf1 =856 client.files.upload(857 docData1, UploadFileConfig.builder().mimeType("application/pdf").build());858 File samplePdf2 =859 client.files.upload(860 docData2, UploadFileConfig.builder().mimeType("application/pdf").build());861862 String prompt =863 "What is the difference between each of the main benchmarks between these two papers? Output these in a table.";864865 Content doc1Content =866 DocumentContent.builder()867 .uri(samplePdf1.uri().orElse(""))868 .mimeType(DocumentContentMimeType.of(samplePdf1.mimeType().orElse("application/pdf")))869 .build();870 Content doc2Content =871 DocumentContent.builder()872 .uri(samplePdf2.uri().orElse(""))873 .mimeType(DocumentContentMimeType.of(samplePdf2.mimeType().orElse("application/pdf")))874 .build();875 Content textContent = TextContent.builder().text(prompt).build();876877 List<Content> contents = Arrays.asList(doc1Content, doc2Content, textContent);878879 CreateModelInteraction params =880 CreateModelInteraction.builder()881 .model(Model.of("gemini-3.8-flash"))882 .input(InteractionsInput.ofContent(contents))883 .build();884885 Interaction interaction =886 client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();887 System.out.println(interaction.outputText().orElse(""));888889### REST890891 DOC_URL_1="https://arxiv.org/pdf/2312.11805"892 DOC_URL_2="https://arxiv.org/pdf/2403.05530"893 DISPLAY_NAME_1="Gemini_paper"894 DISPLAY_NAME_2="Gemini_1.5_paper"895 PROMPT="What is the difference between each of the main benchmarks between these two papers? Output these in a table."896897 # Function to download and upload a PDF898 upload_pdf() {899 local doc_url="$1"900 local display_name="$2"901902 echo "Downloading ${display_name} from ${doc_url}..." >&2903 # Download the PDF904 wget -O "${display_name}.pdf" "${doc_url}" 2> /dev/null905906 local MIME_TYPE=$(file -b --mime-type "${display_name}.pdf")907 local NUM_BYTES=$(wc -c < "${display_name}.pdf")908909 echo "MIME_TYPE: ${MIME_TYPE}" >&2910 echo "NUM_BYTES: ${NUM_BYTES}" >&2911912 local tmp_header_file="upload-header-${display_name}.tmp"913914 # Initial resumable request915 # Using GEMINI_API_KEY instead of GOOGLE_API_KEY916 curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GEMINI_API_KEY}" \917 -D "${tmp_header_file}" \918 -H "X-Goog-Upload-Protocol: resumable" \919 -H "X-Goog-Upload-Command: start" \920 -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \921 -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \922 -H "Content-Type: application/json" \923 -d "{'file': {'display_name': '${display_name}'}}" 2> /dev/null924925 local upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")926 rm "${tmp_header_file}"927928 echo "Upload URL for ${display_name}: ${upload_url}" >&2929930 # Upload the PDF931 curl "${upload_url}" \932 -H "Content-Length: ${NUM_BYTES}" \933 -H "X-Goog-Upload-Offset: 0" \934 -H "X-Goog-Upload-Command: upload, finalize" \935 --data-binary "@${display_name}.pdf" 2> /dev/null > "file_info_${display_name}.json"936937 local file_uri=$(jq -r ".file.uri" "file_info_${display_name}.json")938 echo "file_uri for ${display_name}: ${file_uri}" >&2939940 # Clean up the downloaded PDF941 rm "${display_name}.pdf"942943 echo "${file_uri}"944 }945946 # Upload the first PDF947 file_uri_1=$(upload_pdf "${DOC_URL_1}" "${DISPLAY_NAME_1}")948949 # Upload the second PDF950 file_uri_2=$(upload_pdf "${DOC_URL_2}" "${DISPLAY_NAME_2}")951952 # Create payload JSON file for safety953 cat << EOF > payload_multi.json954 {955 "model": "gemini-3.8-flash",956 "input": [957 {"type": "document", "uri": "${file_uri_1}", "mime_type": "application/pdf"},958 {"type": "document", "uri": "${file_uri_2}", "mime_type": "application/pdf"},959 {"type": "text", "text": "${PROMPT}"}960 ]961 }962 EOF963964 # Now create an interaction using both files965 # Using GEMINI_API_KEY instead of GOOGLE_API_KEY966 curl "https://generativelanguage.googleapis.com/v1beta/interactions" \967 -H "x-goog-api-key: $GEMINI_API_KEY" \968 -H 'Content-Type: application/json' \969 -X POST \970 -d @payload_multi.json 2> /dev/null > response.json971972 cat response.json973 echo974975 jq ".steps[-1].content[0].text" response.json976977 # Clean up978 rm payload_multi.json979 rm "file_info_${DISPLAY_NAME_1}.json"980 rm "file_info_${DISPLAY_NAME_2}.json"981982## Technical details983984Gemini supports PDF files up to 50MB or 1000 pages. This limit applies985to both inline data and Files API uploads. Each document page is equivalent to 258986tokens.987988While there are no specific limits to the number of pixels in a document besides989the model's [context window](https://ai.google.dev/gemini-api/docs/long-context), larger pages are990scaled down to a maximum resolution of 3072 x 3072 while preserving their original991aspect ratio, while smaller pages are scaled up to 768 x 768 pixels. There is no992cost reduction for pages at lower sizes, other than bandwidth, or performance993improvement for pages at higher resolution.994995### Gemini 3 models996997Gemini 3 introduces granular control over multimodal vision processing with the998`media_resolution` parameter. You can now set the resolution to low, medium, or999high per individual media part. With this addition, the processing of PDF1000documents has been updated:100110021. **Native text inclusion:** Text natively embedded in the PDF is extracted and provided to the model.10032. **Billing \& token reporting:**1004 - You are **not charged** for tokens originating from the extracted **native text** in PDFs.1005 - 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.10061007For more details about the media resolution parameter, see the1008[Media resolution](https://ai.google.dev/gemini-api/docs/interactions/media-resolution) guide.10091010### Document types10111012Technically, you can pass other MIME types for document understanding, like1013TXT, Markdown, HTML, XML, etc. However, document vision ***only meaningfully1014understands PDFs***. Other types will be extracted as pure text, and the model1015won't be able to interpret what we see in the rendering of those files. Any1016file-type specifics like charts, diagrams, HTML tags, Markdown formatting, etc.,1017will be lost.10181019To learn about other file input methods, see the1020[File input methods](https://ai.google.dev/gemini-api/docs/file-input-methods) guide.10211022### Best practices10231024For best results:10251026- Rotate pages to the correct orientation before uploading.1027- Avoid blurry pages.1028- If using a single page, place the text prompt after the page.10291030## What's next10311032To learn more, see the following resources:10331034- [File prompting strategies](https://ai.google.dev/gemini-api/docs/files#prompt-guide): The Gemini API supports prompting with text, image, audio, and video data, also known as multimodal prompting.1035- [System instructions](https://ai.google.dev/gemini-api/docs/text-generation#system-instructions): System instructions let you steer the behavior of the model based on your specific needs and use cases.