YouTube publishing¶
Three separate steps put a conversation on YouTube and keep it up to date:
| Step | What it does | Cost of re-running |
|---|---|---|
| Video Upload | Uploads the recording as an unlisted video and waits for YouTube to finish processing it | Expensive — see the warning below |
| Metadata Sync | Pushes the current title and description to that video | Cheap, safe |
| Thumbnail Sync | Pushes the generated thumbnail to that video | Cheap, safe |
A fourth step, Visibility Promote, flips the video from unlisted to public once the consent gate has cleared. It's described at the bottom of this page.
They're split rather than combined because the reasons to re-run them are completely different. Fixing a typo in a title should not mean re-uploading a two-gigabyte video, and regenerating a thumbnail should not risk creating a second copy of the episode.
Connecting a channel is a one-time setup per journey: YouTube setup.
Before you connect: the account doing it must own the channel. For an organisation channel that means a Brand Account whose Owner role the connecting Google account holds. YouTube Studio "Manager" or "Editor" access is enough to upload by hand but is invisible to the API, so the channel simply won't appear at Connect time. See YouTube accounts and channel access.
Video Upload¶
At a glance¶
| Needs | The title and YouTube description, a recording file, and a connected channel |
| Produces | An unlisted YouTube video and its URL |
| Waits when | The title or description isn't written yet, or YouTube is still processing the upload |
| Re-running | Expensive. Reset does not delete the video already on YouTube — a re-run uploads a second copy |
What it does¶
Uploads the recording as unlisted — reachable by link, not public, not searchable — then polls YouTube until processing finishes. Unlisted first is deliberate: participants review the real video, and making it public is a separate step that only runs after they've had their say.
If the journey includes the Video Editor, the cleaned cut is uploaded in preference to the raw recording, whenever that file exists.
Before uploading it checks the recording's length against the channel's permissions — uploads over 15 minutes need a channel verified for long uploads, and failing that check up front is much better than failing it after the upload.
Title and description are trimmed to YouTube's limits (100 and 5,000 characters).
It never uploads twice by accident¶
Once a video ID is stored on the conversation, every retry path re-polls or re-syncs the existing video instead of uploading again. The one way to get a duplicate is to reset the step, which clears METIS's record but cannot delete the video from YouTube. The reset dialog warns about this when a video exists — delete it on YouTube first if that isn't what you want.
Metadata Sync¶
Pushes the current title and description to the already-uploaded video. This is how an edited title reaches YouTube: edit it in the Publishing panel, then re-run (or reset) this step.
It reads the video's current details first and sends them back modified, because YouTube's update replaces the whole record — anything omitted would be wiped. If the journey includes the video editor, chapter timestamps in the description are remapped onto the cleaned timeline here, so they don't drift.
It knows when there's nothing to do. The step remembers a fingerprint of what it last pushed; if the current title and description match, it returns without calling YouTube at all. That makes it safe to leave in a journey that runs repeatedly.
Thumbnail Sync¶
Sets the generated cover image as the video's thumbnail. Cheap and repeatable — re-run it whenever the thumbnail has been regenerated by the Cover Image Generator.
Visibility Promote¶
Flips the video from unlisted to public, and optionally files it in a playlist. In a journey this runs after the consent gate, and that ordering is the whole point: nothing becomes public until the participants have had their window.
- Only the privacy setting changes. Everything else on the video — licence, embedding, made-for-kids, scheduled publishing — is read first and preserved. A video already at the target visibility is left alone.
- The playlist is optional, and set on the step. The step checks whether the video is already in the playlist before adding it, on every pass — so it heals itself if someone removes the video by hand, and files the video into a new playlist if the setting changes. It never removes the video from a playlist it was previously filed in.
- Visibility happens first, deliberately. It is what everything downstream is waiting for, and it shouldn't be held up by a playlist problem. The consequence is that a bad playlist setting leaves the video public with the step incomplete: staff get an actionable error, and the journey holds before announcing. Re-running skips the flip and retries only the playlist.
- Reset does not un-publish. Neither the public flip nor the playlist entry is reversible from METIS.
The channel connection¶
All the YouTube steps in a journey publish to one channel, connected once on the Video Upload step. The sync steps inherit that connection and have no Connect button of their own — a sync authorised against a different channel would be looking for a video that doesn't exist there.
The connected channel's name is shown next to Connected in the step editor and on the conversation's step inspector. That display is the source of truth for where uploads go — always check it after connecting, especially for organisation (Brand Account) channels where it's easy to authorise a personal channel by mistake.
Full walkthrough of the setup: YouTube setup. Which Google account can connect an organisation channel, and how to grant the Owner access the API requires: YouTube accounts and channel access.
Troubleshooting¶
| Symptom | Likely cause | What to do |
|---|---|---|
| Upload waiting, no error | The title or description isn't generated yet | Normal. Check the Content Generator step. |
| Upload waiting for a long time after uploading | YouTube is still processing the video | Normal for long videos. The step polls until it's ready. |
| Error: connection expired or revoked | The channel authorisation is no longer valid | Reconnect on the journey step — the error note names the step |
| Error: upload too long for this channel | The channel isn't verified for uploads over 15 minutes | Verify the channel with YouTube, or use a channel that is |
| Error: permission denied / video not found on a sync step | The sync step is pointed at a different channel than the upload | Clear any separate authorisation on the sync steps so they inherit the upload step's channel |
| Edited the title, YouTube still shows the old one | The metadata sync step hasn't run since | Re-run the metadata sync step |
| Regenerated the thumbnail, YouTube still shows the old one | The thumbnail sync step hasn't run since | Re-run the thumbnail sync step |
| Metadata sync "did nothing" | Nothing changed since it last pushed | Expected — it skips when the content matches what's already there |
| Two copies of the video on the channel | The upload step was reset after a successful upload | Delete the extra video on YouTube. Reset only clears METIS's record. |
| Everything fails at once, mentioning quota | The daily API quota is exhausted | Wait for the daily reset; uploads are the expensive operation (roughly six a day per project) |
| Video is public too early | A promote step is ordered before the consent gate | Fix the journey's step order |
| Video went public but the promote step shows an error | The playlist setting is wrong — visibility is flipped first, on purpose | Fix the playlist on the step and re-run; the flip is skipped and only the playlist is retried |
Technical reference¶
| Step types | youtube_video_upload, youtube_metadata_sync, youtube_thumbnail_sync, youtube_visibility_promote |
| Runs after | Upload: content_generator. Syncs: the upload (thumbnail sync also needs cover_image_generator). Promote: the upload, and in a journey the consent gate |
| Reads | fields.title, fields.youtube_description, artifacts.thumbnail, records.youtube.video_id, and the recording file (the cleaned cut when present) |
| Writes | Upload: records.youtube.{video_id, video_url, visibility, upload_status, processing_status, uploaded_at, processed_at}. Metadata sync: {metadata_synced_at, synced_hash}. Thumbnail sync: {thumbnail_synced_at}. Promote: {promoted_at, promoted_visibility, playlist_id, playlist_item_id, playlist_added_at} |
| Needs on the agent | youtube.client_id, youtube.client_secret — the shared OAuth client |
| Needs on the step | youtube_refresh_token on the upload step, written by the Connect flow. Access tokens are minted per run and never stored |
| Error handling | Server errors, network failures, quota exhaustion and processing delays are retried automatically. A revoked or expired authorisation, a rejected request, or a processing failure at YouTube is a permanent error with a note naming the step to reconnect |
| Quota | ~1,600 units per upload against a 10,000/day default (≈6 uploads/day per project); metadata updates ≈51 units; polls and thumbnail sets are cheaper |
Journeys created before the split had a single combined youtube_uploader step. A
migration repointed it to youtube_video_upload and inserted the two sync steps after it, so
existing journeys keep working; the old bespoke "Sync Status" button was retired in favour of
re-running the metadata sync step.