[null,null,["最后更新时间 (UTC):2025-08-29。"],[[["\u003cp\u003eThis guide explains how to upload large files or files over unreliable networks to Google Photos using resumable uploads.\u003c/p\u003e\n"],["\u003cp\u003eResumable uploads are initiated by a POST request that returns a unique session URL for subsequent upload requests.\u003c/p\u003e\n"],["\u003cp\u003eFiles can be uploaded in a single request or in multiple chunks, with the latter offering flexibility for managing large uploads and progress tracking.\u003c/p\u003e\n"],["\u003cp\u003eIf an upload is interrupted, you can query the server to determine the progress and resume from the appropriate offset.\u003c/p\u003e\n"],["\u003cp\u003eResumable uploads use specific headers for initiating, uploading, and finalizing the transfer process, as well as for resuming interrupted uploads.\u003c/p\u003e\n"]]],["To initiate a resumable upload to the Google Photos Library API, send a POST request with specific headers, including `X-Goog-Upload-Command: start`. The response provides a unique URL and chunk granularity for subsequent requests. Files can be uploaded in a single request or multiple chunks, setting `X-Goog-Upload-Command` to `upload` or `upload, finalize` accordingly, along with `Content-Length` and `X-Goog-Upload-Offset`. Interrupted uploads can be resumed by querying the server for the current upload size and restarting from that point.\n"],null,["# Resumable uploads\n\nThis page describes how to make a resumable upload request to the Google Photos Library API\nvia the REST protocol. This protocol allows you to resume an upload operation\nafter a communication failure interrupts the flow of data.\n\nUse the resumable upload option if:\n\n- You are uploading large files.\n- The likelihood of network interruption or some other transmission failure is high (for example, if you are uploading a file from a mobile app).\n\nResumable uploads can also reduce your bandwidth usage when there is a network\nfailure, because you don't have to restart large file uploads from the\nbeginning.\n| **Note:** If you are sending small files over a reliable network connection, you can use a [simple upload](/photos/library/guides/upload-media).\n\nStep 1: Initiating an upload session\n------------------------------------\n\nInitiate a resumable upload session by sending a POST request to\n`https://photoslibrary.googleapis.com/v1/uploads`. Using the resumable upload\nURL returned in this request, upload the file.\n\nThe POST request must include the following headers:\n\n| Header fields ||\n|------------------------------|----------------------------------------------------------------------|\n| `Content-Length` | Set to `0` as the request body is empty. |\n| `X-Goog-Upload-Command` | Set to `start`. |\n| `X-Goog-Upload-Content-Type` | Set to the mime type of the file, for example, `image/jpeg`. |\n| `X-Goog-Upload-Protocol` | Set to `resumable`. |\n| `X-Goog-Upload-Raw-Size` | Set to the total number of bytes of the file data to be transferred. |\n\nHere is a POST request header: \n\n```\nPOST https://photoslibrary.googleapis.com/v1/uploads\nAuthorization: Bearer oauth2-token\nContent-Length: 0\nX-Goog-Upload-Command: start\nX-Goog-Upload-Content-Type: mime-type\nX-Goog-Upload-Protocol: resumable\nX-Goog-Upload-Raw-Size: bytes-of-file\n```\n\nStep 2: Saving the session URL\n------------------------------\n\nIf successful, the POST request returns a `200 OK` HTTP status code, including\nthe following header. \n\n```\nX-Goog-Upload-URL: url-to-make-uploads-to\nX-Goog-Upload-Chunk-Granularity: chunk-granularity-in-bytes\n```\n\nThe header field `x-goog-upload-chunk-granularity` contains the byte alignment\nand size granularity for all data chunks sent by the client. If the upload is\ndone in [multiple chunks](#upload-file), all uploads, except the last upload,\nmust be done in multiples of this value. That is, the upload bytes of the file\nmust be aligned to this value. In the last chunk, you can upload the remaining\nbytes.\n\nThe header field `X-Goog-Upload-URL` contains a unique URL that must be used to\ncomplete the upload through all of the remaining requests. Copy and save this\nresumable session URL, so that you can use it for subsequent requests.\n| **Note:** A resumable session URL expires after 7 days.\n\nStep 3: Uploading the file\n--------------------------\n\nThere are two ways to upload a file with a resumable session:\n\n1. **In a single request.** This approach is usually the best, because it requires fewer requests, and thus has better performance.\n2. **In multiple chunks.** In this approach, uploads are made\n in multiple requests by chunking the data. The data is chunked in\n multiples of `x-goog-upload-chunk-granularity`. If necessary,\n the chunked requests can be re-tried.\n\n Use this approach if:\n - You need to reduce the amount of data transferred in any single request. You might need to do this when there is a fixed time limit for individual requests.\n - You need to provide a customized indicator showing the upload progress.\n - You need to know when it is safe to discard data.\n\n### Single Request\n\nTo upload the file in a single request:\n\n1. Create a `POST` request to the resumable session URL.\n2. Add the file's data to the request body.\n3. Add the following HTTP headers:\n\n - `Content-Length`: Set to the number of bytes in the file.\n - `X-Goog-Upload-Command`: Set to `upload,\n finalize`.\n4. Send the request.\n\nIf the upload request is interrupted or you receive a `5xx`\nresponse, follow the procedure in [Resuming an\ninterrupted upload](#resume-upload).\n\nIf the request succeeds, you receive a `200 OK` HTTP status\ncode and an upload token in the response body.\n[Create\nthe media item](/photos/library/guides/upload-media#creating-media-item) using this upload token.\n\n### Multiple Chunks\n\nTo upload the file in multiple chunks:\n\n1. Create a `POST` request to the resumable session URL.\n2. Add the chunk's data to the request body.\n\n Except for the final chunk that completes the upload, create the\n other chunks in multiples of the accepted size of chunks. Keep the\n chunk size as large as possible so that the upload is efficient.\n3. Add the following HTTP headers:\n\n - `Content-Length`: Set to the number of bytes in the chunk.\n - `X-Goog-Upload-Command`: Set to `upload`. For the last chunk, set to `upload, finalize`.\n - `X-Goog-Upload-Offset`: Set to the offset at which the bytes should be written. Note that the bytes must be uploaded serially. The first offset is `0`.\n4. Send the request. If the upload request is interrupted or you receive a `5xx`\n response, follow the procedure in [Resuming an\n interrupted upload](#resume-upload).\n\n5. Repeat these steps for each remaining chunk in the file.\n\nIf the request succeeds, you receive a `200 OK` HTTP status\ncode and an upload token in the response body.\n[Create\nthe media item](/photos/library/guides/upload-media#creating-media-item) using this upload token.\n\n### Example\n\n### Single Request\n\nThe following example shows a resumable request to upload a\n3,039,417-byte JPEG file in a single request. \n\n```\nPOST https://photoslibrary.googleapis.com/v1/uploads HTTP/1.1\nContent-Length: 0\nX-Goog-Upload-Command: start\nX-Goog-Upload-Content-Type: image/jpeg\nX-Goog-Upload-Protocol: resumable\nX-Goog-Upload-Raw-Size: 3039417\n[no body]\n```\n\nThe response contains the upload URL and the expected chunk size: \n\n```\nHTTP/1.1 200 OK\nX-Goog-Upload-URL: https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable\nX-Goog-Upload-Chunk-Granularity: 262144\n```\n\nThe final upload request: \n\n```\nPOST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1\nContent-Length: 3039417\nX-Goog-Upload-Command: upload, finalize\nX-Goog-Upload-Offset: 0\n\n[BYTES 0-4199999]\n```\n\n### Multiple Chunks\n\nThe following example shows a resumable request to upload a\n3,039,417-byte JPEG file in multiple chunks, using the resumable session\nURL and the accepted chunk size granularity obtained in the previous step.\nThis example uses a chunk size of 262,144 bytes which was returned in the\nheader field, `x-goog-upload-chunk-granularity`, when the\nupload session was initialized. Note that each upload contains bytes that\nare in multiples of 262,144.\n\nInitialize the upload session to receive the upload URL and chunk size\nas described in the previous step: \n\n```\nPOST https://photoslibrary.googleapis.com/v1/uploads HTTP/1.1\nContent-Length: 0\nX-Goog-Upload-Command: start\nX-Goog-Upload-Content-Type: image/jpeg\nX-Goog-Upload-Protocol: resumable\nX-Goog-Upload-Raw-Size: 3039417\n[no body]\n```\n\nThe response contains the upload URL and the expected chunk size: \n\n```\nHTTP/1.1 200 OK\nX-Goog-Upload-URL: https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable\nX-Goog-Upload-Chunk-Granularity: 262144\n```\n\nFirst chunk: \n\n```\nPOST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1\nContent-Length: 1048576\nX-Goog-Upload-Command: upload\nX-Goog-Upload-Offset: 0\n\n[BYTES 0-1048575]\n```\n\nSecond chunk: \n\n```\nPOST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1\nContent-Length: 1048576\nX-Goog-Upload-Command: upload\nX-Goog-Upload-Offset: 1048576\n\n[BYTES 1048576-2097151]\n```\n\nLast chunk: \n\n```\nPOST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1\nContent-Length: 942265\nX-Goog-Upload-Command: upload, finalize\nX-Goog-Upload-Offset: 2097152\n\n[BYTES 2097152-4200000]\n```\n\nResuming an interrupted upload\n------------------------------\n\nIf the upload request is interrupted or if you receive a non-`200` HTTP status\ncode, query the server to find out how much of the upload succeeded.\n\nHere is a `POST` request to the resumable session URL. `X-Goog-Upload-Command`\nshould be set to `query`. \n\n```\nPOST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1\nContent-Length: 0\nX-Goog-Upload-Command: query\n```\n\nThe response from the server includes a `200 OK` HTTP status code and the\ncurrent size of the upload. \n\n```\nHTTP/1.1 200 OK\nX-Goog-Upload-Status: active\nX-Goog-Upload-Size-Received: 100\n```\n\nYou can then resume uploading at this offset. You must resume at the offset\nprovided by the server unless you send a combined upload and finalize command,\nin which case you can also resume at offset 0.\n\nIf the `X-Goog-Upload-Status` header in the HTTP response of your query command\nis present and the value is not `active`, that indicates that the upload has\nalready been terminated."]]