Skip to content

Get YouTube posting credentials

Set up a Google Cloud OAuth app so keryx auth youtube can capture a refresh token and keryx post youtube can upload a reel as a Short. This mirrors the Instagram credentials guide; the difference is Google's OAuth (a durable refresh token + 1-hour access tokens) and a longer approval path for public uploads.

Status: app-registration steps (§1–§5) are ready to follow now — this is the long-lead item, so start it early. The keryx auth youtube / posting sections (§6+) are filled in as the adapter lands (spec 0007-youtube.md).

What you need

  • A Google account that owns a YouTube channel (the channel you'll post to).
  • ~20 minutes for the Cloud Console setup; the verification/audit for public posting is separate and takes weeks (see §5) — uploads stay private until it's done, which is fine for building and testing.

1. Create a Google Cloud project

  1. Go to the Google Cloud Consolehttps://console.cloud.google.com/.
  2. Project picker (top bar) → New Project. Name it e.g. keryx. Create, then select it.

2. Enable the YouTube Data API v3

  1. APIs & Services → Library (https://console.cloud.google.com/apis/library).
  2. Search "YouTube Data API v3" → open it → Enable.

APIs & Services → OAuth consent screen (https://console.cloud.google.com/apis/credentials/consent):

  1. User type: External (choose Internal only if this is a Google Workspace org and the channel is inside it). Create.
  2. App information: app name (keryx), your user support email, and a developer contact email.
  3. Scopes → Add or remove scopes → manually add: https://www.googleapis.com/auth/youtube.upload This is a restricted scope (it's what triggers the verification/CASA requirement for public use in §5). Save.
  4. Test users → Add users: add the Google account that owns the channel. While the app is in Testing, only listed test users can authorise it.
  5. Save.

4. Create the OAuth client (Desktop app)

APIs & Services → Credentials (https://console.cloud.google.com/apis/credentials):

  1. Create credentials → OAuth client ID.
  2. Application type: Desktop app. Name it (keryx-cli). Create.
  3. Copy the Client ID and Client secret. These are what keryx needs:
  4. platforms.youtube.client_id (non-secret) — goes in keryx config.
  5. YOUTUBE_CLIENT_SECRET (secret) — env var / keychain, never committed.

Desktop-app clients use the loopback redirect (http://127.0.0.1:<port>) that keryx already serves — no redirect URL to register (Google allows any loopback port, RFC 8252). Nothing to paste into the console here.

5. Publishing status & the audit (the long pole)

On the OAuth consent screen, the app starts in Testing:

  • Testing: usable immediately by your test users, but refresh tokens expire after 7 days — fine for a first end-to-end test, not for unattended use.
  • Publish App → "In production": refresh tokens become durable (no 7-day expiry). You can publish even while unverified; you (the owner/test user) click past the "Google hasn't verified this app" screen. Do this to get a lasting refresh token.
  • Public uploads (so videos aren't forced to private and quota isn't capped) additionally require app verification + the YouTube API Audit & Quota Extension + a CASA security assessment. This is the weeks-long part. Until it's granted, keryx keeps platforms.youtube.privacy: private.

For now: enable the API (§2), set up consent (§3), create the Desktop client (§4), and Publish to "In production" (§5) so the refresh token persists. Defer the full audit until the implementation is confirmed working on private uploads. Start the Audit & Quota Extension when you're ready to go public.

Official references

  • YouTube Data API v3 — Uploads and videos.insert guides.
  • Google Identity — Using OAuth 2.0 for Installed/Desktop Applications and Loopback IP address flow.
  • Google API Services — OAuth verification, Restricted scopes, and the YouTube API Services Audit (incl. CASA).

6. Authorise keryx

With the client id in config (platforms.youtube.client_id), the secret in the environment (YOUTUBE_CLIENT_SECRET), and the app published to production:

keryx auth youtube

It prints (and tries to open) a Google authorize URL and runs a plain-http loopback callback on a free port — no cert, no warning. Approve the YouTube permission (click past the one-time "Google hasn't verified this app" → Advanced → Go to keryx), and it captures the code, exchanges it for a refresh token, and stores it (keychain on a desktop, else the config file). platforms.youtube.enabled flips true.

  • Remote/headless box: the redirect targets 127.0.0.1:<port> on your machine, so reach the host the same way as the Instagram flow — an SSH port-forward, or change the address-bar host to the box's LAN IP. Pin a fixed port with --redirect http://127.0.0.1:<port>/ if you need to forward it.
  • Scope note: keryx requests only youtube.upload, which can't read channels.list, so the channel id is recorded best-effort — it isn't needed to upload (videos.insert targets the authorised channel).

Once authorised, keryx post youtube uploads a rendered reel as a private Short (until the audit lifts the cap). The capture flow reuses keryx auth.