> ## AI Agent Context > Get the complete documentation index at: https://aistudio.google.com/llms.txt > Use this file to discover all available pages. > For the full documentation in a single file, fetch: https://aistudio.google.com/llms-full.txt # Creating a file {% mark class="http-post" %}{% icon name="north_east" /%}`POST`{% /mark %} `https://generativelanguage.googleapis.com/v1beta/files` Creates a [`File`](/api-reference/files/create-file#Resource:File). {% two-column-layout %} {% left-column %} ## Request Body {% class="hide-from-toc" id="request-body" %} {% section class="api-ref-property-list" %} **file**: [`File`](/api-reference/files/create-file#Resource:File) Optional. Metadata for the file to create. {% /section %} {% /left-column %} {% right-column class="sticky" %} **Example request** {% class="example-heading" %} {% tabs %} {% tab label="Image" %} {% tabs %} {% tab label="REST" %} ```sh MIME_TYPE=$(file -b --mime-type "${IMG_PATH_2}") NUM_BYTES=$(wc -c < "${IMG_PATH_2}") DISPLAY_NAME=TEXT tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \ -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \ -H "Content-Type: application/json" \ -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r") rm "${tmp_header_file}" # Upload the actual bytes. curl "${upload_url}" \ -H "Content-Length: ${NUM_BYTES}" \ -H "X-Goog-Upload-Offset: 0" \ -H "X-Goog-Upload-Command: upload, finalize" \ --data-binary "@${IMG_PATH_2}" 2> /dev/null > file_info.json file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri # Now generate content using that file curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ "contents": [{ "parts":[ {"text": "Can you tell me about the instruments in this photo?"}, {"file_data": {"mime_type": "image/jpeg", "file_uri": '$file_uri'} }] }] }' 2> /dev/null > response.json cat response.json echo jq ".candidates[].content.parts[].text" response.json ``` {% /tab %} {% tab label="Python" %} ```python from google import genai client = genai.Client() myfile = client.files.upload(file=media / "Cajun_instruments.jpg") print(f"{myfile=}") result = client.models.generate_content( model="gemini-3.8-flash", contents=[ myfile, "\n\n", "Can you tell me about the instruments in this photo?", ], ) print(f"{result.text=}") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript // Make sure to include the following import: // import {GoogleGenAI} from '@google/genai'; const ai = new GoogleGenAI({apiKey: process.env.GEMINI_API_KEY}); const myfile = await ai.files.upload({ file: path.join(media, 'Cajun_instruments.jpg'), config: {mimeType: 'image/jpeg'}, }); console.log('Uploaded file:', myfile); const result = await ai.models.generateContent({ model: 'gemini-3.8-flash', contents: createUserContent([ createPartFromUri(myfile.uri, myfile.mimeType), '\n\n', 'Can you tell me about the instruments in this photo?', ]), }); console.log('result.text=', result.text); ``` {% /tab %} {% tab label="Go" %} ```go ctx := context.Background() client, err := genai.NewClient(ctx, &genai.ClientConfig{ APIKey: os.Getenv("GEMINI_API_KEY"), Backend: genai.BackendGeminiAPI, }) if err != nil { log.Fatal(err) } myfile, err := client.Files.UploadFromPath( ctx, filepath.Join(getMedia(), "Cajun_instruments.jpg"), &genai.UploadFileConfig{ MIMEType: "image/jpeg", }, ) if err != nil { log.Fatal(err) } fmt.Printf("myfile=%+v\n", myfile) parts := []*genai.Part{ genai.NewPartFromURI(myfile.URI, myfile.MIMEType), genai.NewPartFromText("\n\n"), genai.NewPartFromText("Can you tell me about the instruments in this photo?"), } contents := []*genai.Content{ genai.NewContentFromParts(parts, genai.RoleUser), } response, err := client.Models.GenerateContent(ctx, "gemini-3.8-flash", contents, nil) if err != nil { log.Fatal(err) } text := response.Text() fmt.Printf("result.text=%s\n", text) ``` {% /tab %} {% /tabs %} {% /tab %} {% tab label="Audio" %} {% tabs %} {% tab label="REST" %} ```sh MIME_TYPE=$(file -b --mime-type "${AUDIO_PATH}") NUM_BYTES=$(wc -c < "${AUDIO_PATH}") DISPLAY_NAME=AUDIO tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \ -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \ -H "Content-Type: application/json" \ -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r") rm "${tmp_header_file}" # Upload the actual bytes. curl "${upload_url}" \ -H "Content-Length: ${NUM_BYTES}" \ -H "X-Goog-Upload-Offset: 0" \ -H "X-Goog-Upload-Command: upload, finalize" \ --data-binary "@${AUDIO_PATH}" 2> /dev/null > file_info.json file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri # Now generate content using that file curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ "contents": [{ "parts":[ {"text": "Describe this audio clip"}, {"file_data":{"mime_type": "audio/mp3", "file_uri": '$file_uri'}}] }] }' 2> /dev/null > response.json cat response.json echo jq ".candidates[].content.parts[].text" response.json ``` {% /tab %} {% tab label="Python" %} ```python from google import genai client = genai.Client() myfile = client.files.upload(file=media / "sample.mp3") print(f"{myfile=}") result = client.models.generate_content( model="gemini-3.8-flash", contents=[myfile, "Describe this audio clip"] ) print(f"{result.text=}") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript // Make sure to include the following import: // import {GoogleGenAI} from '@google/genai'; const ai = new GoogleGenAI({apiKey: process.env.GEMINI_API_KEY}); const myfile = await ai.files.upload({ file: path.join(media, 'sample.mp3'), config: {mimeType: 'audio/mpeg'}, }); console.log('Uploaded file:', myfile); const result = await ai.models.generateContent({ model: 'gemini-3.8-flash', contents: createUserContent([ createPartFromUri(myfile.uri, myfile.mimeType), 'Describe this audio clip', ]), }); console.log('result.text=', result.text); ``` {% /tab %} {% tab label="Go" %} ```go ctx := context.Background() client, err := genai.NewClient(ctx, &genai.ClientConfig{ APIKey: os.Getenv("GEMINI_API_KEY"), Backend: genai.BackendGeminiAPI, }) if err != nil { log.Fatal(err) } myfile, err := client.Files.UploadFromPath( ctx, filepath.Join(getMedia(), "sample.mp3"), &genai.UploadFileConfig{ MIMEType: "audio/mpeg", }, ) if err != nil { log.Fatal(err) } fmt.Printf("myfile=%+v\n", myfile) parts := []*genai.Part{ genai.NewPartFromURI(myfile.URI, myfile.MIMEType), genai.NewPartFromText("Describe this audio clip"), } contents := []*genai.Content{ genai.NewContentFromParts(parts, genai.RoleUser), } response, err := client.Models.GenerateContent(ctx, "gemini-3.8-flash", contents, nil) if err != nil { log.Fatal(err) } text := response.Text() fmt.Printf("result.text=%s\n", text) ``` {% /tab %} {% /tabs %} {% /tab %} {% tab label="Text" %} {% tabs %} {% tab label="REST" %} ```sh MIME_TYPE=$(file -b --mime-type "${TEXT_PATH}") NUM_BYTES=$(wc -c < "${TEXT_PATH}") DISPLAY_NAME=TEXT tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \ -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \ -H "Content-Type: application/json" \ -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r") rm "${tmp_header_file}" # Upload the actual bytes. curl "${upload_url}" \ -H "Content-Length: ${NUM_BYTES}" \ -H "X-Goog-Upload-Offset: 0" \ -H "X-Goog-Upload-Command: upload, finalize" \ --data-binary "@${TEXT_PATH}" 2> /dev/null > file_info.json file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri # Now generate content using that file curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ "contents": [{ "parts":[ {"text": "Can you add a few more lines to this poem?"}, {"file_data":{"mime_type": "text/plain", "file_uri": '$file_uri'}}] }] }' 2> /dev/null > response.json cat response.json echo jq ".candidates[].content.parts[].text" response.json name=$(jq ".file.name" file_info.json) # Get the file of interest to check state curl https://generativelanguage.googleapis.com/v1beta/files/$name > file_info.json # Print some information about the file you got name=$(jq ".file.name" file_info.json) echo name=$name file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri curl --request "DELETE" https://generativelanguage.googleapis.com/v1beta/files/$name?key=$GEMINI_API_KEY ``` {% /tab %} {% tab label="Python" %} ```python from google import genai client = genai.Client() myfile = client.files.upload(file=media / "poem.txt") print(f"{myfile=}") result = client.models.generate_content( model="gemini-3.8-flash", contents=[myfile, "\n\n", "Can you add a few more lines to this poem?"], ) print(f"{result.text=}") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript // Make sure to include the following import: // import {GoogleGenAI} from '@google/genai'; const ai = new GoogleGenAI({apiKey: process.env.GEMINI_API_KEY}); const myfile = await ai.files.upload({ file: path.join(media, 'poem.txt'), }); console.log('Uploaded file:', myfile); const result = await ai.models.generateContent({ model: 'gemini-3.8-flash', contents: createUserContent([ createPartFromUri(myfile.uri, myfile.mimeType), '\n\n', 'Can you add a few more lines to this poem?', ]), }); console.log('result.text=', result.text); ``` {% /tab %} {% tab label="Go" %} ```go ctx := context.Background() client, err := genai.NewClient(ctx, &genai.ClientConfig{ APIKey: os.Getenv("GEMINI_API_KEY"), Backend: genai.BackendGeminiAPI, }) if err != nil { log.Fatal(err) } myfile, err := client.Files.UploadFromPath( ctx, filepath.Join(getMedia(), "poem.txt"), &genai.UploadFileConfig{ MIMEType: "text/plain", }, ) if err != nil { log.Fatal(err) } fmt.Printf("myfile=%+v\n", myfile) parts := []*genai.Part{ genai.NewPartFromURI(myfile.URI, myfile.MIMEType), genai.NewPartFromText("\n\n"), genai.NewPartFromText("Can you add a few more lines to this poem?"), } contents := []*genai.Content{ genai.NewContentFromParts(parts, genai.RoleUser), } response, err := client.Models.GenerateContent(ctx, "gemini-3.8-flash", contents, nil) if err != nil { log.Fatal(err) } text := response.Text() fmt.Printf("result.text=%s\n", text) ``` {% /tab %} {% /tabs %} {% /tab %} {% tab label="Video" %} {% tabs %} {% tab label="REST" %} ```sh MIME_TYPE=$(file -b --mime-type "${VIDEO_PATH}") NUM_BYTES=$(wc -c < "${VIDEO_PATH}") DISPLAY_NAME=VIDEO_PATH # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \ -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \ -H "Content-Type: application/json" \ -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r") rm "${tmp_header_file}" # Upload the actual bytes. curl "${upload_url}" \ -H "Content-Length: ${NUM_BYTES}" \ -H "X-Goog-Upload-Offset: 0" \ -H "X-Goog-Upload-Command: upload, finalize" \ --data-binary "@${VIDEO_PATH}" 2> /dev/null > file_info.json file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri state=$(jq ".file.state" file_info.json) echo state=$state # Ensure the state of the video is 'ACTIVE' while [[ "($state)" = *"PROCESSING"* ]]; do echo "Processing video..." sleep 5 # Get the file of interest to check state curl https://generativelanguage.googleapis.com/v1beta/files/$name > file_info.json state=$(jq ".file.state" file_info.json) done # Now generate content using that file curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ "contents": [{ "parts":[ {"text": "Describe this video clip"}, {"file_data":{"mime_type": "video/mp4", "file_uri": '$file_uri'}}] }] }' 2> /dev/null > response.json cat response.json echo jq ".candidates[].content.parts[].text" response.json ``` {% /tab %} {% tab label="Python" %} ```python from google import genai import time client = genai.Client() # Video clip (CC BY 3.0) from https://peach.blender.org/download/ myfile = client.files.upload(file=media / "Big_Buck_Bunny.mp4") print(f"{myfile=}") # Poll until the video file is completely processed (state becomes ACTIVE). while not myfile.state or myfile.state.name != "ACTIVE": print("Processing video...") print("File state:", myfile.state) time.sleep(5) myfile = client.files.get(name=myfile.name) result = client.models.generate_content( model="gemini-3.8-flash", contents=[myfile, "Describe this video clip"] ) print(f"{result.text=}") ``` {% /tab %} {% tab label="JavaScript" %} ```javascript // Make sure to include the following import: // import {GoogleGenAI} from '@google/genai'; const ai = new GoogleGenAI({apiKey: process.env.GEMINI_API_KEY}); let myfile = await ai.files.upload({ file: path.join(media, 'Big_Buck_Bunny.mp4'), config: {mimeType: 'video/mp4'}, }); console.log('Uploaded video file:', myfile); // Poll until the video file is completely processed (state becomes ACTIVE). while (!myfile.state || myfile.state.toString() !== 'ACTIVE') { console.log('Processing video...'); console.log('File state: ', myfile.state); await sleep(5000); myfile = await ai.files.get({name: myfile.name}); } const result = await ai.models.generateContent({ model: 'gemini-3.8-flash', contents: createUserContent([ createPartFromUri(myfile.uri, myfile.mimeType), 'Describe this video clip', ]), }); console.log('result.text=', result.text); ``` {% /tab %} {% tab label="Go" %} ```go ctx := context.Background() client, err := genai.NewClient(ctx, &genai.ClientConfig{ APIKey: os.Getenv("GEMINI_API_KEY"), Backend: genai.BackendGeminiAPI, }) if err != nil { log.Fatal(err) } myfile, err := client.Files.UploadFromPath( ctx, filepath.Join(getMedia(), "Big_Buck_Bunny.mp4"), &genai.UploadFileConfig{ MIMEType: "video/mp4", }, ) if err != nil { log.Fatal(err) } fmt.Printf("myfile=%+v\n", myfile) // Poll until the video file is completely processed (state becomes ACTIVE). for myfile.State == genai.FileStateUnspecified || myfile.State != genai.FileStateActive { fmt.Println("Processing video...") fmt.Println("File state:", myfile.State) time.Sleep(5 * time.Second) myfile, err = client.Files.Get(ctx, myfile.Name, nil) if err != nil { log.Fatal(err) } } parts := []*genai.Part{ genai.NewPartFromURI(myfile.URI, myfile.MIMEType), genai.NewPartFromText("Describe this video clip"), } contents := []*genai.Content{ genai.NewContentFromParts(parts, genai.RoleUser), } response, err := client.Models.GenerateContent(ctx, "gemini-3.8-flash", contents, nil) if err != nil { log.Fatal(err) } text := response.Text() fmt.Printf("result.text=%s\n", text) ``` {% /tab %} {% /tabs %} {% /tab %} {% tab label="Pdf" %} {% tabs %} {% tab label="Python" %} ```python from google import genai client = genai.Client() sample_pdf = client.files.upload(file=media / "test.pdf") response = client.models.generate_content( model="gemini-3.8-flash", contents=["Give me a summary of this pdf file.", sample_pdf], ) print(response.text) ``` {% /tab %} {% tab label="Go" %} ```go ctx := context.Background() client, err := genai.NewClient(ctx, &genai.ClientConfig{ APIKey: os.Getenv("GEMINI_API_KEY"), Backend: genai.BackendGeminiAPI, }) if err != nil { log.Fatal(err) } samplePdf, err := client.Files.UploadFromPath( ctx, filepath.Join(getMedia(), "test.pdf"), &genai.UploadFileConfig{ MIMEType: "application/pdf", }, ) if err != nil { log.Fatal(err) } parts := []*genai.Part{ genai.NewPartFromText("Give me a summary of this pdf file."), genai.NewPartFromURI(samplePdf.URI, samplePdf.MIMEType), } contents := []*genai.Content{ genai.NewContentFromParts(parts, genai.RoleUser), } response, err := client.Models.GenerateContent(ctx, "gemini-3.8-flash", contents, nil) if err != nil { log.Fatal(err) } text := response.Text() fmt.Println(text) ``` {% /tab %} {% /tabs %} {% /tab %} {% /tabs %} {% /right-column %} {% /two-column-layout %} ## Response {% class="hide-from-toc" id="response" %} {% section class="api-ref-property-list" %} **file**: [`File`](/api-reference/files/create-file#Resource:File) Metadata for the created file. {% /section %} ## Resources {% class="hide-from-toc" id="resources" %} ### File {% class="hide-from-toc" id="Resource:File" %} A file uploaded to the API. **Properties:** {% details %} {% summary %} **metadata**: `Union type` Metadata for the File. {% /summary %} Union field `metadata` can be only one of the following: {% details %} {% summary %} **videoMetadata**: `VideoFileMetadata` Output only. Metadata for a video. {% /summary %} **videoDuration**: `string` Duration of the video. {% /details %} {% /details %} {% hr /%} **name**: `string` Immutable. Identifier. The [`File`](/api-reference/files/create-file#Resource:File) resource name. The ID (name excluding the "files/" prefix) can contain up to 40 characters that are lowercase alphanumeric or dashes (-). The ID cannot start or end with a dash. If the name is empty on create, a unique name will be generated. Example: `files/123-456` {% hr /%} **displayName**: `string` Optional. The human-readable display name for the [`File`](/api-reference/files/create-file#Resource:File). The display name must be no more than 512 characters in length, including spaces. Example: "Welcome Image" {% hr /%} **mimeType**: `string` Output only. MIME type of the file. {% hr /%} **sizeBytes**: `string` Output only. Size of the file in bytes. {% hr /%} **createTime**: `string` Output only. The timestamp of when the [`File`](/api-reference/files/create-file#Resource:File) was created. {% hr /%} **updateTime**: `string` Output only. The timestamp of when the [`File`](/api-reference/files/create-file#Resource:File) was last updated. {% hr /%} **expirationTime**: `string` Output only. The timestamp of when the [`File`](/api-reference/files/create-file#Resource:File) will be deleted. Only set if the [`File`](/api-reference/files/create-file#Resource:File) is scheduled to expire. {% hr /%} **sha256Hash**: `string` Output only. SHA-256 hash of the uploaded bytes. {% hr /%} **uri**: `string` Output only. The uri of the [`File`](/api-reference/files/create-file#Resource:File). {% hr /%} **downloadUri**: `string` Output only. The download uri of the [`File`](/api-reference/files/create-file#Resource:File). {% hr /%} {% details %} {% summary %} **state**: `enum (string)` Output only. Processing state of the File. {% /summary %} Possible values: - `STATE_UNSPECIFIED`: The default value. This value is used if the state is omitted. - `PROCESSING`: File is being processed and cannot be used for inference yet. - `ACTIVE`: File is processed and available for inference. - `FAILED`: File failed processing. {% /details %} {% hr /%} {% details %} {% summary %} **source**: `enum (string)` Source of the File. {% /summary %} Possible values: - `SOURCE_UNSPECIFIED`: Used if source is not specified. - `UPLOADED`: Indicates the file is uploaded by the user. - `GENERATED`: Indicates the file is generated by Google. - `REGISTERED`: Indicates the file is a registered, i.e. a Google Cloud Storage file. {% /details %} {% hr /%} **error**: [`Status`](/api-reference/files/create-file#Resource:Status) Output only. Error status if File processing failed. ## Data Models {% class="hide-from-toc" id="data-models" %} ### Status {% class="hide-from-toc" id="Resource:Status" %} The [`Status`](/api-reference/files/create-file#Resource:Status) type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each [`Status`](/api-reference/files/create-file#Resource:Status) message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors). **Properties:** **code**: `integer` The status code, which should be an enum value of google.rpc.Code. {% hr /%} **message**: `string` A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the google.rpc.Status.details field, or localized by the client. {% hr /%} **details**: `array (object)` A list of messages that carry the error details. There is a common set of message types for APIs to use.