Skip to main content
RapidDev - Software Development Agency

How to Automate YouTube Video Uploads using the API

YouTube videos.insert requires resumable upload: POST for a session URI, then PUT video chunks in multiples of 256 KB. The critical gotcha since July 28, 2020: ALL videos uploaded via unaudited API projects are FORCED to private and cannot be made public — you must pass the YouTube API Compliance Audit first. The youtube.upload scope is Restricted and also requires the audit. Quota cost is disputed (100 vs 1,600 units) — verify in Cloud Console. With 10,000 units/day, you may only get 6–100 uploads per day.

Need help automating? Talk to an expert
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced6 min read60–120 minutesYouTubeLast updated May 2026RapidDev Engineering Team
TL;DR

YouTube videos.insert requires resumable upload: POST for a session URI, then PUT video chunks in multiples of 256 KB. The critical gotcha since July 28, 2020: ALL videos uploaded via unaudited API projects are FORCED to private and cannot be made public — you must pass the YouTube API Compliance Audit first. The youtube.upload scope is Restricted and also requires the audit. Quota cost is disputed (100 vs 1,600 units) — verify in Cloud Console. With 10,000 units/day, you may only get 6–100 uploads per day.

Quick facts about this guide
FactValue
PlatformYouTube
Rate limits10,000 quota units/day per project (not per user), resets midnight Pacific…
DifficultyAdvanced
Time required60–120 minutes
Last updatedMay 2026

API Quick Reference

Auth

Rate limit

10,000 quota units/day per project (not per user), resets midnight Pacific Time. Separate per-100s rate limits visible in Cloud Console.

Format

SDK

REST only

YouTube Data API v3 — Video Upload Automation

YouTube videos.insert uses resumable upload — a two-phase protocol required for large files. Phase 1: POST request to get a session URI. Phase 2: PUT the video bytes in chunks that are multiples of 256 KB. The session URI stays valid for 1 week. For failures mid-upload, resume by sending a range query. The most important compliance requirement: as of July 28, 2020, ALL video uploads from unaudited API projects are permanently forced to private status. The uploaded video cannot be made public through the API or YouTube Studio unless the GCP project passes the YouTube API Compliance Audit. This affects any project created after July 28, 2020 that has not been audited.

Base URLhttps://www.googleapis.com/upload/youtube/v3

Authentication

Key endpoints

POST

Phase 1: Initiate resumable upload session. Send video metadata in the body, receive a Location header with the session URI. The session URI is valid for 1 week.

PUT

Phase 2: Upload the video binary. Send in chunks that are MULTIPLES OF 256 KB. For resuming after failure, first send a range query to find where to resume.

PUT

Update video metadata after upload: change title, description, tags, privacy status, or thumbnails. Costs 50 quota units.

POST

Set a custom thumbnail for an uploaded video. Requires a verified YouTube channel (phone-verified). Image must be under 2 MB, at least 640x360 pixels, max 1280x720.

GET

Check upload status and get processing progress after upload. Use to poll until uploadStatus changes from 'uploaded' to 'processed'.

Step-by-step automation

1

Step 1: Set Up OAuth Authentication

Configure OAuth 2.0 with youtube.upload scope. Remember: service accounts do NOT work with YouTube APIs.

request.sh
1# Get authorization URL open in browser
2https://accounts.google.com/o/oauth2/v2/auth?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&response_type=code&scope=https://www.googleapis.com/auth/youtube.upload&access_type=offline&prompt=consent
3
4# Exchange authorization code for tokens
5curl -X POST https://oauth2.googleapis.com/token \
6 -H 'Content-Type: application/x-www-form-urlencoded' \
7 -d 'code=AUTH_CODE&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&redirect_uri=REDIRECT_URI&grant_type=authorization_code'
2

Step 2: Initiate Resumable Upload Session

Phase 1 of upload: send video metadata and file info to get a session URI. The session URI is used in Phase 2 to send the actual video bytes.

request.sh
1# Phase 1: Initiate upload session (no video bytes yet)
2curl -X POST \
3 -H 'Authorization: Bearer ACCESS_TOKEN' \
4 -H 'Content-Type: application/json' \
5 -H 'X-Upload-Content-Type: video/mp4' \
6 -H 'X-Upload-Content-Length: 157286400' \
7 'https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=snippet,status' \
8 -d '{
9 "snippet": {
10 "title": "My Automated Upload",
11 "description": "Uploaded via YouTube API",
12 "tags": ["tutorial", "automation"],
13 "categoryId": "22"
14 },
15 "status": {
16 "privacyStatus": "private",
17 "selfDeclaredMadeForKids": false
18 }
19 }'
20# Response: 200 with Location header containing session_uri
3

Step 3: Execute Upload with Progress Tracking

Phase 2: Upload the video bytes with progress tracking. The google-api-python-client handles chunking automatically. For Node.js, implement manual chunking.

request.sh
1# Phase 2: Upload first chunk
2curl -X PUT SESSION_URI \
3 -H 'Content-Length: 8388608' \
4 -H 'Content-Range: bytes 0-8388607/157286400' \
5 --data-binary @chunk_0_8mb.bin
6# Response 308 = more chunks needed
7# Response 200/201 = complete
8
9# Resume after interruption (find where to resume)
10curl -X PUT SESSION_URI \
11 -H 'Content-Length: 0' \
12 -H 'Content-Range: bytes */157286400'
13# Response includes Range: bytes=0-N showing what was received
4

Step 4: Update Metadata After Upload

Update video title, description, or privacy status after upload. Costs 50 quota units per call.

request.sh
1# Update video metadata after upload
2curl -X PUT \
3 -H 'Authorization: Bearer ACCESS_TOKEN' \
4 -H 'Content-Type: application/json' \
5 'https://www.googleapis.com/youtube/v3/videos?part=snippet,status' \
6 -d '{
7 "id": "VIDEO_ID",
8 "snippet": {
9 "title": "Updated Title",
10 "description": "Updated description with more detail.",
11 "categoryId": "22",
12 "tags": ["updated", "tag"]
13 },
14 "status": {
15 "privacyStatus": "public"
16 }
17 }'
5

Step 5: Check Processing Status

After upload, YouTube processes the video (transcoding, thumbnail generation). Poll processingDetails until uploadStatus is 'processed'.

request.sh
1# Check processing status
2curl -H 'Authorization: Bearer ACCESS_TOKEN' \
3 'https://www.googleapis.com/youtube/v3/videos?part=status,processingDetails&id=VIDEO_ID'

Complete working code

Full video upload pipeline: validates the file, uploads with resumable protocol, sets a custom thumbnail, updates metadata, and waits for processing. Includes compliance audit status checking.

Error handling

Cause

Your GCP project has not passed the YouTube API Compliance Audit. Since July 28, 2020, ALL videos uploaded via unaudited projects are permanently locked to private status, regardless of the privacyStatus field you send. This affects any project created after that date without an audit.

Fix

Cause

You've hit the 10,000 daily quota limit. With videos.insert costing potentially 1,600 units, this means as few as 6 uploads can exhaust the daily budget. The quota resets at midnight Pacific Time.

Fix

Cause

Common causes: unsupported video format, file corrupt, total file size doesn't match X-Upload-Content-Length header, or chunk size not a multiple of 256 KB.

Fix

Cause

Resumable upload session URIs expire after 1 week. If you created the session and waited more than 7 days before completing the upload, the session is gone.

Fix

Cause

Normal for long videos or high platform load. YouTube processing time scales with video length, resolution, and codec. A 4K 1-hour video can take 30+ minutes to process.

Fix

Rate limits & throttling

Security checklist

  • Always start uploads with privacyStatus='private' — make videos public only after reviewing the uploaded content, even if your project has passed the audit
  • Store OAuth tokens and credentials files with restricted file permissions (chmod 600) and outside the web root
  • Never commit credentials.json or token.json to version control — add them to .gitignore immediately
  • Implement upload size validation before initiating a session — reject files over YouTube's 256 GB limit and unsupported formats
  • For automated upload pipelines, validate video titles and descriptions for policy compliance before uploading to avoid strikes or channel termination
  • Set selfDeclaredMadeForKids correctly — uploading COPPA-regulated children's content without this flag can result in legal liability and channel termination
  • Log all uploads with video IDs, timestamps, and uploader identity for audit trails
  • Implement webhook or polling notifications to your team when uploads complete — do not leave uploaded videos unreviewed

Automation use cases

No-code alternatives

Don't want to write code? These platforms can automate the same workflows visually.

Zapier

YouTube integration in Zapier includes a 'Upload Video' action. Triggers can be new files in Google Drive, Dropbox, or Box. Handles OAuth automatically and abstracts the resumable upload protocol.

Pros
    Cons

      Make (Integromat)

      YouTube 'Upload a Video' module handles the full upload. More flexible than Zapier for complex metadata templates and multi-step scenarios (upload > thumbnail > update description). Monitors upload progress.

      Pros
        Cons

          n8n

          YouTube node with video upload support. HTTP Request nodes can handle custom resumable upload scenarios. Best for complex automation with error handling and conditional logic.

          Pros
            Cons

              Best practices

              • Submit the YouTube API Compliance Audit before building any upload automation — without it, every uploaded video is permanently locked as private regardless of your privacyStatus setting
              • Always use resumable upload (uploadType=resumable) for video files — simple upload (uploadType=media) is limited to 5 MB and will fail for any real video
              • Use chunk sizes that are exact multiples of 256 KB (262,144 bytes) — the last chunk can be any size, but all intermediate chunks must be multiples
              • Start uploads with privacyStatus='private' and change to public after review — even for automated pipelines, a review step reduces policy violation risk
              • Set selfDeclaredMadeForKids accurately — this is a legal requirement under COPPA/GDPR for child-directed content
              • Store resumable upload session URIs in a database with creation timestamps — valid for 1 week, allowing you to resume interrupted uploads rather than starting over
              • Verify the actual videos.insert quota cost in Cloud Console — the disputed 100 vs 1,600 unit cost makes a major difference in your upload capacity planning
              • Use categoryId from videoCategories.list with your regionCode — categories vary by region, and some category IDs are not assignable (assignable=false)

              Ask AI to help

              Copy one of these prompts to get a personalized, working implementation.

              ChatGPT / Claude Prompt

              I'm building a YouTube video upload automation using YouTube Data API v3. Key requirements: (1) resumable upload protocol (POST for session URI, PUT chunks in 256KB multiples), (2) privacyStatus must be 'private' until after YouTube API Compliance Audit, (3) check processing status via videos.list with processingDetails part, (4) handle 10,000 unit/day quota (videos.insert disputed cost: 100 vs 1,600 units), (5) retry on 500/503 errors with exponential backoff. Use Python with google-api-python-client MediaFileUpload. OAuth only — no service accounts.

              Lovable / V0 Prompt

              Build a video upload tool for content creators. UI: drag-and-drop file upload, form for title/description/tags/category/privacy, thumbnail upload, submit button. After submit: show upload progress bar (percentage), then processing status indicator. When complete, show the YouTube video URL. Backend calls YouTube Data API v3 resumable upload. Warn the user if the video gets locked as private (Compliance Audit requirement). Store upload history in Supabase.

              Frequently asked questions

              Why are all my uploaded videos locked as private even though I set privacyStatus='public'?

              Your GCP project has not passed the YouTube API Compliance Audit. Since July 28, 2020, all videos uploaded via the API from unaudited projects are automatically forced to private status. This applies regardless of what privacyStatus you send. Submit the YouTube API Services Compliance Audit form at console.cloud.google.com. Until your project is audited and approved, you cannot make API-uploaded videos public — not via the API and not via YouTube Studio.

              How many videos can I upload per day with the YouTube Data API?

              It depends on the disputed quota cost for videos.insert. If the cost is 100 units, you can upload 100 videos/day on the 10,000 unit free quota. If it's 1,600 units (which many sources report), you can only upload 6 videos/day. Check your actual consumption in Cloud Console > APIs & Services > Quotas after a test upload. For more than 10,000 units/day, submit the YouTube API Services Audit and Quota Extension Form.

              What is resumable upload and why is it required?

              Resumable upload is a two-phase protocol: Phase 1 sends video metadata and gets a session URI. Phase 2 sends the actual video bytes in chunks to that URI. It's required because video files are too large for simple HTTP POST requests, and it allows you to resume a failed upload from where it stopped rather than starting over. Session URIs are valid for 1 week. Chunk sizes must be multiples of 256 KB (262,144 bytes).

              Can I use a service account to upload videos on behalf of multiple YouTube channels?

              No. Service accounts are not supported by any YouTube API — they return NoLinkedYouTubeAccount because a service account has no YouTube channel. For multi-channel upload automation, each channel's owner must authorize your app via OAuth, and you must store separate refresh tokens for each channel. There is no workaround for this limitation.

              What categoryId should I use for my videos?

              Call videoCategories.list with your target regionCode to get the list of valid categories and their assignable status. Common IDs: 22 = People & Blogs, 10 = Music, 20 = Gaming, 28 = Science & Technology, 27 = Education, 24 = Entertainment. Not all categories are assignable (assignable=false) and some categories vary by region.

              Can RapidDev help build a video upload pipeline for my platform?

              Yes. If you need to automate video publishing to YouTube as part of a content workflow — pulling from Google Drive, applying consistent metadata templates, setting thumbnails, and tracking processing status — RapidDev can build that pipeline. We also help navigate the Compliance Audit requirements so your videos can actually go public.

              What happens if my upload is interrupted halfway through?

              For resumable uploads, you can recover. Send a PUT to the session URI with Content-Range: bytes */TOTAL_SIZE and Content-Length: 0 to get a 308 Resume Incomplete response with a Range header showing how many bytes the server received. Then resume the upload from byte (Range end + 1). Session URIs are valid for 1 week from creation — after that you must start over.

              RapidDev

              Need this automated?

              Our team has built 600+ apps with API automations. We can build this for you.

              Book a free consultation
              Matt Graham

              Written by

              Matt Graham · CEO & Founder, RapidDev

              1,000+ client projects delivered. Columbia University & Harvard Business School alumnus, U.S. Navy veteran. About the author →

              Want this built for you?

              We ship production apps at a fixed price — $13K–$25K, 6–10 weeks, source code yours. You've seen what it takes; we do it every week.

              Get a fixed-price quote

              We put the rapid in RapidDev

              Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.