헤더 필드 x-goog-upload-chunk-granularity에는 바이트 정렬이 포함되어 있습니다.
및 크기 세부사항을 설정할 수 있습니다. 업로드 상태가
여러 단위로 수행(마지막 업로드를 제외한 모든 업로드)
이 값의 배수로 지정해야 합니다. 즉, 파일의 업로드 바이트가 이 값에 정렬되어야 합니다. 마지막 청크에서 나머지 덩어리를
바이트.
헤더 필드 X-Goog-Upload-URL에는 나머지 모든 요청을 통해 업로드를 완료하는 데 사용해야 하는 고유한 URL이 포함되어 있습니다. 후속 요청에 사용할 수 있도록 이 재개 가능한 세션 URL을 복사하여 저장합니다.
3단계: 파일 업로드
재개 가능한 세션으로 파일을 업로드하는 방법에는 두 가지가 있습니다.
단일 요청. 이 접근 방식이 일반적으로 가장 좋으며
필요한 요청이 더 적기 때문에 성능이 더 우수하기 때문입니다.
여러 단위. 이 접근 방식에서는 데이터를 청크로 나눠 여러 요청으로 업로드합니다. 데이터는
x-goog-upload-chunk-granularity의 배수입니다. 필요한 경우
청크로 분할된 요청을 다시 시도할 수 있습니다.
다음과 같은 경우 이 방법을 사용합니다.
단일 전송에서 전송되는 데이터의 양을 줄여야 하고
요청을 수행합니다. 개별 요청에 고정된 시간 제한이 있는 경우 이 작업을 수행해야 할 수 있습니다.
다음 예는 재개 가능한 세션 URL과 이전 단계에서 가져온 허용된 청크 크기 세부사항을 사용하여 3,039,417바이트 JPEG 파일을 여러 청크로 업로드하는 재개 가능한 요청을 보여줍니다.
이 예에서는
헤더 필드 x-goog-upload-chunk-granularity가 반환되면
업로드 세션이 초기화되었습니다. 각 업로드에는
262,144의 배수입니다
[null,null,["최종 업데이트: 2025-08-29(UTC)"],[[["\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."]]