Google Photos Upload

There is basically no real tutorial on how to add files to Google Photos in n8n. Everything out there shows Google Drive, but there is no native Google Photos node, so you are on your own.

After way too many hours fighting with ChatGPT and Claude, here is what actually works.

You must use HTTP Request nodes. Two of them.

First request uploads the photo to Google Photos and returns an uploadToken. This is a raw binary upload and the headers matter. If the content type is wrong, it will silently fail or upload garbage.

Second request takes that uploadToken and creates the media item in Google Photos. This is where you can also set things like creationTime if you care about timestamps.

One more thing that will absolutely break your workflow if you miss it. If you send multiple requests to Google Photos at the same time, it will fall apart. Random failures, missing photos, no errors, just pain.

You need to add a random delay between uploads so they do not all start at once. Even a small randomized delay fixes it. Without it, Google Photos will shit the bed.

This is not obvious, not documented, and cost me hours. Hopefully this saves someone else the headache.

The two http requests:

POST #1 Upload the binary and get an upload token

Endpoint
photolibrary.googleapis dot com/v1/uploads

Purpose
This request uploads the raw image file to Google Photos and returns an uploadToken. This token does not create a photo yet. It is just a temporary reference Google gives you after accepting the binary.

Key settings

  • Method POST

  • Auth Google OAuth2 with Photos Library scope

  • Content Type application/octet-stream

  • X-Goog-Upload-Protocol raw

  • X-Goog-Upload-File-Name any filename you want

  • Body type n8n Binary File

  • Input data field name must match your binary field, usually data

Important notes

  • This request must send raw binary. If it goes as text or JSON it will fail silently.

  • Response format must be Text. The response body is the uploadToken string.

  • File name header matters more than you think. Keep it simple and valid.

Output
A plain text uploadToken. Nothing else.

POST #2 Create the media item in Google Photos

Endpoint
photolibrary.googleapis dot com/v1/mediaitems:batchCreate

Purpose
This request tells Google Photos to turn the uploadToken into an actual photo in your library. This is where the photo is created and optionally added to an album.

Key settings

  • Method POST

  • Auth Google OAuth2

  • Content Type application/json

  • Body type JSON

Example body structure

  • albumId optional

  • newMediaItems array

    • simpleMediaItem

      • uploadToken from POST #1

Optional
You can also set mediaMetadata.creationTime here if you want correct timestamps.

Important notes

  • This request will succeed even if the uploadToken is bad, but the photo will never appear.

  • Always pass exactly one uploadToken per media item.

  • Do not batch too aggressively.

Critical gotcha Google Photos concurrency

If you run multiple uploads at the same time, Google Photos will randomly fail. No errors. Missing photos. Inconsistent behavior.

You must add a randomized delay between uploads so requests do not start at the same time. Even a small delay fixes most issues.

Without this, everything looks correct and still breaks.

This is undocumented behavior and will cost you hours if you do not account for it.

Hope this helps!