YouTube Publishing Pipeline

The only pipeline with no image stage — the generated video is the post, published through a per-run OAuth token exchange and a resumable byte upload.

Client
EpsolDev
Category
Automation Engineering
Completed
2026-08-15
Built with
n8n, Google Vertex AI, REST API
Topics
API Development, Automation
YouTube Publishing Pipeline

n8n 47 nodes Video-only Publishing daily

The odd one out. Every other pipeline in the set generates an image and treats video as an optional extra. Here the video is the post — there is no image generation node anywhere in the graph.

The whole YouTube workflow: caption, video generation with its polling loop, OAuth exchange and the resumable upload

Part of the Social Distribution Network.


Straight from caption to video

Dispatch, the site loop, the schedule gate and the claim gate

The shared front half is identical to the others — dispatch, Loop Over Sites, YT Due?, claim gate, CBM Next Post → CBM Get Identity → CBM Get Prompts → Build Prompts.

Then it diverges immediately:

Has Topic? -> Gen Caption -> Parse Caption -> Veo Submit Primary
                                                     │
                                             ( no image path exists )

The caption becomes the title and description. Everything else is the video.


One generative service, one polling loop

Caption generation and the video submission branch with its fallback

Video generation is asynchronous — you submit and receive an operation handle, not a file. So the graph submits, falls back if the submit failed, and then polls:

Veo Submit Primary -> Have Op 1? ─┬─ yes ─> Prep Op
                                  └─ no  ─> Wait Fallback -> Veo Submit Fallback
                                                                     │
                                                             Have Op 2? ─┬─ yes ─> Prep Op
                                                                         └─ no  ─> Gen Failed

Prep Op -> Wait Poll -> Veo Poll -> Poll Gate -> Video Ready?
               ^                                   │      │
               └───── no ─── Give Up? ─────────────┘      yes -> Capture Video

Give Up? is what keeps this bounded. Without it a stuck generation would hold an execution slot indefinitely.


The only pipeline that exchanges a token

Credential fetch, the OAuth token exchange, and the resumable upload chain

Instagram and Facebook accept a long-lived token directly. YouTube does not — it needs a short-lived access token minted from a stored refresh token on every run:

CBM Get YT Creds -> Parse Creds -> Creds OK?
                                       │
                                  YT Token Exchange -> Token Gate -> Token OK?

Token Gate and Token OK? exist because a refresh token can be revoked between runs. A revoked token exits to the site loop; it never reaches the upload. Discovering that after pushing a video's bytes would waste the most expensive thing the workflow produces.


A resumable upload, not a form post

Video bytes are too large for a single request, so YouTube uses a two-phase protocol:

  • YT Init Upload — declare the metadata, receive an upload target
  • Prep Video — shape the bytes for that target
  • YT Upload Bytes — send them
  • Verify Publish → Published? — confirm the video exists before recording it

No media round-trip through the content platform. Unlike the image pipelines, nothing is uploaded to the library and nothing needs deleting — the bytes go from the generator straight to YouTube.


Why it earns its own graph

Same skeleton, four genuine divergences: no image stage, a token exchange, a resumable upload, and a caption that serves as title and description rather than a body. Merging this into the image pipelines would have meant branching around every one of those.


Stack

n8n YouTube Data API OAuth 2.0 Google Vertex AI Veo JavaScript REST API

All projects